@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,14 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { checkProjectAccess } from '@lucern/access-control/access';
|
|
1
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
2
|
+
import { componentsGeneric, internalMutationGeneric, queryGeneric, mutationGeneric } from 'convex/server';
|
|
4
3
|
import '@lucern/access-control/audience';
|
|
5
4
|
import { getCurrentUserId } from '@lucern/access-control/auth';
|
|
6
|
-
import {
|
|
5
|
+
import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
|
|
6
|
+
import { normalizeTupleContradictionPolicy, mkOpinion, conditionalDeduction, project, dampedDependencyCascade, deriveContractModulationPlan, deriveContractStatus, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, confidenceFromSL, detectTupleContradiction, evaluateTupleContradictionTransition, readOpinionFromRecord, parseEvidentialEvaluatorConfig, compareMetricValue, resolveComparisonResult, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig, hasProjectedOpinionChanged, createInheritedContractRecord } from '@lucern/confidence';
|
|
7
|
+
import { v } from 'convex/values';
|
|
7
8
|
import '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
|
|
9
|
+
import { checkProjectAccess, requireScopeWriteAccess } from '@lucern/access-control/access';
|
|
8
10
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
9
11
|
import { generateGlobalId } from '@lucern/contracts/ids';
|
|
10
12
|
|
|
11
|
-
// src/
|
|
13
|
+
// src/convex.ts
|
|
14
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
15
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
16
|
+
);
|
|
17
|
+
var api = unsafeApi;
|
|
18
|
+
componentsGeneric();
|
|
19
|
+
var internal = unsafeApi;
|
|
20
|
+
var internalMutation = internalMutationGeneric;
|
|
21
|
+
var mutation = mutationGeneric;
|
|
22
|
+
var query = queryGeneric;
|
|
23
|
+
|
|
24
|
+
// src/debug.ts
|
|
25
|
+
function isGraphPrimitiveDebugEnabled() {
|
|
26
|
+
const env = globalThis.process?.env;
|
|
27
|
+
return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
|
|
28
|
+
}
|
|
29
|
+
function debugGraphPrimitiveFallback(message, context) {
|
|
30
|
+
if (!isGraphPrimitiveDebugEnabled()) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
console.debug(message, context ?? {});
|
|
34
|
+
}
|
|
12
35
|
|
|
13
36
|
// src/beliefLifecycle.ts
|
|
14
37
|
var BELIEF_STATUS_VALUES = [
|
|
@@ -130,24 +153,6 @@ function promoteBeliefStatusAfterScoring(status, opts) {
|
|
|
130
153
|
}
|
|
131
154
|
return status;
|
|
132
155
|
}
|
|
133
|
-
var api = anyApi;
|
|
134
|
-
componentsGeneric();
|
|
135
|
-
var internal = anyApi;
|
|
136
|
-
var internalMutation = internalMutationGeneric;
|
|
137
|
-
var mutation = mutationGeneric;
|
|
138
|
-
var query = queryGeneric;
|
|
139
|
-
|
|
140
|
-
// src/debug.ts
|
|
141
|
-
function isGraphPrimitiveDebugEnabled() {
|
|
142
|
-
const env = globalThis.process?.env;
|
|
143
|
-
return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
|
|
144
|
-
}
|
|
145
|
-
function debugGraphPrimitiveFallback(message, context) {
|
|
146
|
-
if (!isGraphPrimitiveDebugEnabled()) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
console.debug(message, context ?? {});
|
|
150
|
-
}
|
|
151
156
|
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
152
157
|
async function resolveTopicNodeScopeOrNull(ctx, ref) {
|
|
153
158
|
if (!ctx?.db || typeof ctx.db.query !== "function") {
|
|
@@ -182,13 +187,15 @@ function asMappedProjectId(topic) {
|
|
|
182
187
|
if (!topic) {
|
|
183
188
|
return;
|
|
184
189
|
}
|
|
185
|
-
const directLegacyProjectId = normalizeScopeValue(
|
|
190
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
191
|
+
topic[LEGACY_SCOPE_FIELD]
|
|
192
|
+
);
|
|
186
193
|
if (directLegacyProjectId) {
|
|
187
194
|
return directLegacyProjectId;
|
|
188
195
|
}
|
|
189
196
|
const metadata = topic.metadata || {};
|
|
190
197
|
const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
191
|
-
return candidate ? candidate : void 0;
|
|
198
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
192
199
|
}
|
|
193
200
|
function normalizeScopeValue(value) {
|
|
194
201
|
if (typeof value !== "string") {
|
|
@@ -213,8 +220,9 @@ function pickPrimaryTopic(candidates) {
|
|
|
213
220
|
})[0];
|
|
214
221
|
}
|
|
215
222
|
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
223
|
+
const query2 = ctx.db.query("topics");
|
|
216
224
|
try {
|
|
217
|
-
return await
|
|
225
|
+
return await query2.withIndex(
|
|
218
226
|
"by_graph_scope_project",
|
|
219
227
|
(q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
|
|
220
228
|
).collect();
|
|
@@ -226,7 +234,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
|
226
234
|
scopeId
|
|
227
235
|
}
|
|
228
236
|
);
|
|
229
|
-
const topics = await
|
|
237
|
+
const topics = await query2.collect();
|
|
230
238
|
return topics.filter((topic) => {
|
|
231
239
|
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
232
240
|
const mappedProjectId = asMappedProjectId(topic);
|
|
@@ -282,137 +290,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
|
282
290
|
let current = topic;
|
|
283
291
|
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
284
292
|
current = await ctx.db.get(current.parentTopicId);
|
|
285
|
-
if (!current)
|
|
293
|
+
if (!current) {
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
286
296
|
if (!tenantId) {
|
|
287
297
|
tenantId = normalizeScopeValue(current.tenantId);
|
|
288
298
|
}
|
|
289
299
|
if (!workspaceId) {
|
|
290
300
|
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
291
301
|
}
|
|
292
|
-
if (tenantId && workspaceId)
|
|
302
|
+
if (tenantId && workspaceId) {
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
293
305
|
}
|
|
294
306
|
return { tenantId, workspaceId };
|
|
295
307
|
}
|
|
296
308
|
async function resolveTopicProjectScope(ctx, args) {
|
|
297
309
|
if (args.topicId) {
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
topic = await ctx.db.get(
|
|
301
|
-
args.topicId
|
|
302
|
-
);
|
|
303
|
-
} catch (error) {
|
|
304
|
-
debugGraphPrimitiveFallback(
|
|
305
|
-
"[topicScope] Failed to load topic by direct id",
|
|
306
|
-
{
|
|
307
|
-
error,
|
|
308
|
-
topicId: args.topicId
|
|
309
|
-
}
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
if (!topic) {
|
|
313
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
314
|
-
}
|
|
315
|
-
if (!topic) {
|
|
316
|
-
topic = pickPrimaryTopic(
|
|
317
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
318
|
-
) ?? null;
|
|
319
|
-
}
|
|
320
|
-
if (!topic) {
|
|
321
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
322
|
-
ctx,
|
|
323
|
-
String(args.topicId)
|
|
324
|
-
);
|
|
325
|
-
if (nodeScope) {
|
|
326
|
-
return nodeScope;
|
|
327
|
-
}
|
|
328
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
329
|
-
}
|
|
330
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
331
|
-
const mapped = asMappedProjectId(topic);
|
|
332
|
-
if (mapped) {
|
|
333
|
-
return {
|
|
334
|
-
topicId: topic._id,
|
|
335
|
-
projectId: mapped,
|
|
336
|
-
tenantId: inherited.tenantId,
|
|
337
|
-
workspaceId: inherited.workspaceId,
|
|
338
|
-
source: "topic"
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
return {
|
|
342
|
-
topicId: topic._id,
|
|
343
|
-
tenantId: inherited.tenantId,
|
|
344
|
-
workspaceId: inherited.workspaceId,
|
|
345
|
-
source: "topic"
|
|
346
|
-
};
|
|
310
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
347
311
|
}
|
|
348
312
|
if (args.projectId) {
|
|
349
|
-
|
|
350
|
-
try {
|
|
351
|
-
directTopic = await ctx.db.get(
|
|
352
|
-
args.projectId
|
|
353
|
-
);
|
|
354
|
-
} catch (error) {
|
|
355
|
-
debugGraphPrimitiveFallback(
|
|
356
|
-
"[topicScope] Failed to load direct project topic",
|
|
357
|
-
{
|
|
358
|
-
error,
|
|
359
|
-
projectId: args.projectId
|
|
360
|
-
}
|
|
361
|
-
);
|
|
362
|
-
}
|
|
363
|
-
if (directTopic) {
|
|
364
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
365
|
-
const mapped = asMappedProjectId(directTopic);
|
|
366
|
-
return {
|
|
367
|
-
topicId: directTopic._id,
|
|
368
|
-
projectId: mapped ?? args.projectId,
|
|
369
|
-
tenantId: inherited.tenantId,
|
|
370
|
-
workspaceId: inherited.workspaceId,
|
|
371
|
-
source: "topic_inferred"
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
375
|
-
if (directTopic) {
|
|
376
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
377
|
-
const mapped = asMappedProjectId(directTopic);
|
|
378
|
-
return {
|
|
379
|
-
topicId: directTopic._id,
|
|
380
|
-
projectId: mapped ?? args.projectId,
|
|
381
|
-
tenantId: inherited.tenantId,
|
|
382
|
-
workspaceId: inherited.workspaceId,
|
|
383
|
-
source: "topic_inferred"
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
387
|
-
const primary = pickPrimaryTopic(topics);
|
|
388
|
-
if (primary) {
|
|
389
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
390
|
-
return {
|
|
391
|
-
topicId: primary._id,
|
|
392
|
-
projectId: args.projectId,
|
|
393
|
-
tenantId: inherited.tenantId,
|
|
394
|
-
workspaceId: inherited.workspaceId,
|
|
395
|
-
source: "project_mapped_topic"
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
399
|
-
ctx,
|
|
400
|
-
String(args.projectId)
|
|
401
|
-
);
|
|
402
|
-
if (nodeScope) {
|
|
403
|
-
return {
|
|
404
|
-
...nodeScope,
|
|
405
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
throw new Error(
|
|
409
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
410
|
-
);
|
|
313
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
411
314
|
}
|
|
412
315
|
throw new Error(
|
|
413
316
|
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
414
317
|
);
|
|
415
318
|
}
|
|
319
|
+
async function resolveScopeFromTopicId(ctx, topicId) {
|
|
320
|
+
const topic = await resolveTopicDocFromTopicId(ctx, topicId);
|
|
321
|
+
if (topic) {
|
|
322
|
+
return await buildTopicScope(ctx, topic, "topic");
|
|
323
|
+
}
|
|
324
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
|
|
325
|
+
if (nodeScope) {
|
|
326
|
+
return nodeScope;
|
|
327
|
+
}
|
|
328
|
+
throw new Error(`Topic not found: ${String(topicId)}`);
|
|
329
|
+
}
|
|
330
|
+
async function resolveTopicDocFromTopicId(ctx, topicId) {
|
|
331
|
+
const direct = await tryReadTopicDoc(ctx, topicId, {
|
|
332
|
+
failureLog: "[topicScope] Failed to load topic by direct id",
|
|
333
|
+
idLogKey: "topicId"
|
|
334
|
+
});
|
|
335
|
+
if (direct) {
|
|
336
|
+
return direct;
|
|
337
|
+
}
|
|
338
|
+
const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
|
|
339
|
+
if (hostTopic) {
|
|
340
|
+
return hostTopic;
|
|
341
|
+
}
|
|
342
|
+
return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
|
|
343
|
+
}
|
|
344
|
+
async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
|
|
345
|
+
const directTopic = await resolveDirectLegacyProjectTopic(
|
|
346
|
+
ctx,
|
|
347
|
+
legacyProjectId
|
|
348
|
+
);
|
|
349
|
+
if (directTopic) {
|
|
350
|
+
return await buildTopicScope(ctx, directTopic, "topic_inferred", {
|
|
351
|
+
fallbackProjectId: legacyProjectId
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
const primary = pickPrimaryTopic(
|
|
355
|
+
await findTopicsByScopeAlias(ctx, legacyProjectId)
|
|
356
|
+
);
|
|
357
|
+
if (primary) {
|
|
358
|
+
return await buildTopicScope(ctx, primary, "project_mapped_topic", {
|
|
359
|
+
fallbackProjectId: legacyProjectId
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
|
|
363
|
+
if (nodeScope) {
|
|
364
|
+
return {
|
|
365
|
+
...nodeScope,
|
|
366
|
+
projectId: nodeScope.projectId ?? legacyProjectId
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
throw new Error(
|
|
370
|
+
`Legacy project scope ${legacyProjectId} has no mapped topic.`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
|
|
374
|
+
const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
|
|
375
|
+
failureLog: "[topicScope] Failed to load direct project topic",
|
|
376
|
+
idLogKey: "projectId"
|
|
377
|
+
});
|
|
378
|
+
return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
|
|
379
|
+
}
|
|
380
|
+
async function tryReadTopicDoc(ctx, id, log) {
|
|
381
|
+
try {
|
|
382
|
+
return await ctx.db.get(id);
|
|
383
|
+
} catch (error) {
|
|
384
|
+
debugGraphPrimitiveFallback(log.failureLog, {
|
|
385
|
+
error,
|
|
386
|
+
[log.idLogKey]: id
|
|
387
|
+
});
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
async function buildTopicScope(ctx, topic, source, options = {}) {
|
|
392
|
+
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
393
|
+
const mapped = asMappedProjectId(topic);
|
|
394
|
+
return {
|
|
395
|
+
topicId: topic._id,
|
|
396
|
+
...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
|
|
397
|
+
tenantId: inherited.tenantId,
|
|
398
|
+
workspaceId: inherited.workspaceId,
|
|
399
|
+
source
|
|
400
|
+
};
|
|
401
|
+
}
|
|
416
402
|
({
|
|
417
403
|
projectId: v.optional(v.string()),
|
|
418
404
|
topicId: v.optional(v.string())
|
|
@@ -480,9 +466,10 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
|
|
|
480
466
|
if (resolved.tenantId || resolved.workspaceId) {
|
|
481
467
|
return resolved;
|
|
482
468
|
}
|
|
483
|
-
|
|
469
|
+
const topicId = normalizeScopeValue2(node.topicId);
|
|
470
|
+
if (topicId) {
|
|
484
471
|
const topicScope = await resolveTopicProjectScope(ctx, {
|
|
485
|
-
topicId
|
|
472
|
+
topicId
|
|
486
473
|
});
|
|
487
474
|
return {
|
|
488
475
|
...resolved,
|
|
@@ -502,33 +489,11 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
|
|
|
502
489
|
}
|
|
503
490
|
return resolved;
|
|
504
491
|
}
|
|
505
|
-
|
|
506
|
-
// src/epistemicBeliefs.helpers.ts
|
|
507
492
|
v.id("epistemicNodes");
|
|
508
493
|
var DEFAULT_CONFIDENCE_POLICY = {
|
|
509
494
|
scoringMode: "after_worktree",
|
|
510
495
|
tupleContradiction: normalizeTupleContradictionPolicy()
|
|
511
496
|
};
|
|
512
|
-
function throwStructuredMutationError(args) {
|
|
513
|
-
const data = {
|
|
514
|
-
structuredMutationError: true,
|
|
515
|
-
message: args.message,
|
|
516
|
-
status: args.status,
|
|
517
|
-
code: args.code,
|
|
518
|
-
invariantCode: args.invariantCode,
|
|
519
|
-
suggestion: args.suggestion,
|
|
520
|
-
details: args.details
|
|
521
|
-
};
|
|
522
|
-
const error = new ConvexError(
|
|
523
|
-
data
|
|
524
|
-
);
|
|
525
|
-
error.status = args.status;
|
|
526
|
-
error.code = args.code;
|
|
527
|
-
error.invariantCode = args.invariantCode;
|
|
528
|
-
error.suggestion = args.suggestion;
|
|
529
|
-
error.details = args.details;
|
|
530
|
-
throw error;
|
|
531
|
-
}
|
|
532
497
|
function buildBeliefConfidenceRow(args) {
|
|
533
498
|
return {
|
|
534
499
|
beliefId: args.beliefId,
|
|
@@ -603,7 +568,10 @@ function resolveBeliefStatus(node, metadata) {
|
|
|
603
568
|
});
|
|
604
569
|
}
|
|
605
570
|
async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
|
|
606
|
-
const clusterMembership = await ctx.db.query("worktreeBeliefCluster").withIndex(
|
|
571
|
+
const clusterMembership = await ctx.db.query("worktreeBeliefCluster").withIndex(
|
|
572
|
+
"by_belief",
|
|
573
|
+
(q) => q.eq("beliefId", beliefNodeId)
|
|
574
|
+
).collect();
|
|
607
575
|
for (const membership of clusterMembership) {
|
|
608
576
|
const worktree = await ctx.db.get(membership.worktreeId);
|
|
609
577
|
if (worktree?.status === "completed" || worktree?.status === "merged") {
|
|
@@ -614,7 +582,10 @@ async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
|
|
|
614
582
|
}
|
|
615
583
|
async function getActiveConfidencePolicy(ctx) {
|
|
616
584
|
try {
|
|
617
|
-
const activeConfig = await ctx.db.query("logicSprintScoring").withIndex(
|
|
585
|
+
const activeConfig = await ctx.db.query("logicSprintScoring").withIndex(
|
|
586
|
+
"by_active",
|
|
587
|
+
(q) => q.eq("isActive", true)
|
|
588
|
+
).first();
|
|
618
589
|
return {
|
|
619
590
|
scoringMode: activeConfig?.confidencePolicy === "always" ? "always" : DEFAULT_CONFIDENCE_POLICY.scoringMode,
|
|
620
591
|
tupleContradiction: normalizeTupleContradictionPolicy(
|
|
@@ -631,23 +602,6 @@ async function getActiveConfidencePolicy(ctx) {
|
|
|
631
602
|
return DEFAULT_CONFIDENCE_POLICY;
|
|
632
603
|
}
|
|
633
604
|
}
|
|
634
|
-
async function requireProjectWriteAccess(ctx, projectId, userId) {
|
|
635
|
-
const hasAccess = await checkProjectAccess(
|
|
636
|
-
ctx,
|
|
637
|
-
projectId,
|
|
638
|
-
userId
|
|
639
|
-
);
|
|
640
|
-
if (!hasAccess) {
|
|
641
|
-
throwStructuredMutationError({
|
|
642
|
-
message: `Project write access denied for topic ${projectId}.`,
|
|
643
|
-
status: 403,
|
|
644
|
-
code: "PROJECT_ACCESS_DENIED",
|
|
645
|
-
invariantCode: "policy.scope_required",
|
|
646
|
-
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.",
|
|
647
|
-
details: { topicId: projectId, principalId: userId }
|
|
648
|
-
});
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
605
|
|
|
652
606
|
// src/edges/contains.ts
|
|
653
607
|
var containsPropagationSpec = {
|
|
@@ -784,7 +738,7 @@ var dependsOnPropagationSpec = {
|
|
|
784
738
|
description: "Structural gating. Textbook conditional deduction when edge conditionals exist, otherwise damped dependency cascade through downstream chains."
|
|
785
739
|
};
|
|
786
740
|
|
|
787
|
-
// src/edges/
|
|
741
|
+
// src/edges/derived-from.ts
|
|
788
742
|
var derivedFromPropagationSpec = {
|
|
789
743
|
edgeType: "derived_from",
|
|
790
744
|
direction: "incoming",
|
|
@@ -837,7 +791,7 @@ var informsPropagationSpec = {
|
|
|
837
791
|
description: "Evidence-bearing influence. Informs can chain through the graph with light per-hop damping."
|
|
838
792
|
};
|
|
839
793
|
|
|
840
|
-
// src/edges/
|
|
794
|
+
// src/edges/propagation-types.ts
|
|
841
795
|
function isPropagationTraversalDirection(direction) {
|
|
842
796
|
return direction === "outgoing" || direction === "incoming";
|
|
843
797
|
}
|
|
@@ -910,6 +864,9 @@ var testsPropagationSpec = {
|
|
|
910
864
|
};
|
|
911
865
|
|
|
912
866
|
// src/edges/index.ts
|
|
867
|
+
var canContinueTransitively2 = canContinueTransitively;
|
|
868
|
+
var canTraverseHop2 = canTraverseHop;
|
|
869
|
+
var isPropagationTraversalDirection2 = isPropagationTraversalDirection;
|
|
913
870
|
var EDGE_PROPAGATION_SPECS = [
|
|
914
871
|
supportsPropagationSpec,
|
|
915
872
|
informsPropagationSpec,
|
|
@@ -926,16 +883,15 @@ function getEdgePropagationSpecs() {
|
|
|
926
883
|
return EDGE_PROPAGATION_SPECS;
|
|
927
884
|
}
|
|
928
885
|
function getTraversalDirections(direction) {
|
|
929
|
-
if (
|
|
886
|
+
if (isPropagationTraversalDirection2(direction)) {
|
|
930
887
|
return [direction];
|
|
931
888
|
}
|
|
932
889
|
return ["outgoing", "incoming"];
|
|
933
890
|
}
|
|
934
891
|
|
|
935
892
|
// src/confidencePropagationDispatch.ts
|
|
936
|
-
function
|
|
937
|
-
|
|
938
|
-
return targetNodeId ?? void 0;
|
|
893
|
+
function nodeIdToCacheKey(nodeId) {
|
|
894
|
+
return String(nodeId);
|
|
939
895
|
}
|
|
940
896
|
function readNodeOpinion(node) {
|
|
941
897
|
const metadata = node.metadata ?? {};
|
|
@@ -951,118 +907,354 @@ function readNodeOpinion(node) {
|
|
|
951
907
|
return mkOpinion(0, 0, 1, 0.5);
|
|
952
908
|
}
|
|
953
909
|
}
|
|
910
|
+
function resolveTraversalTargetNodeId(edge, direction) {
|
|
911
|
+
const targetNodeId = direction === "outgoing" ? edge.toNodeId : edge.fromNodeId;
|
|
912
|
+
return targetNodeId ?? void 0;
|
|
913
|
+
}
|
|
914
|
+
function buildInitialState(sourceNodeId, sourceOpinion) {
|
|
915
|
+
return {
|
|
916
|
+
nodeId: sourceNodeId,
|
|
917
|
+
opinion: sourceOpinion,
|
|
918
|
+
hop: 0,
|
|
919
|
+
visitedNodeIds: /* @__PURE__ */ new Set([nodeIdToCacheKey(sourceNodeId)])
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
function extendVisited(currentVisited, targetNodeId) {
|
|
923
|
+
return /* @__PURE__ */ new Set([...currentVisited, nodeIdToCacheKey(targetNodeId)]);
|
|
924
|
+
}
|
|
925
|
+
function makeTransitiveState(current, targetNodeId, projectedOpinion, nextHop) {
|
|
926
|
+
return {
|
|
927
|
+
nodeId: targetNodeId,
|
|
928
|
+
opinion: projectedOpinion,
|
|
929
|
+
hop: nextHop,
|
|
930
|
+
visitedNodeIds: extendVisited(current.visitedNodeIds, targetNodeId)
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
function makeDispatchRecord(targetNodeId, spec, direction, edge, projectedOpinion, nextHop, result, existingDispatch) {
|
|
934
|
+
return {
|
|
935
|
+
targetNodeId,
|
|
936
|
+
edgeType: spec.edgeType,
|
|
937
|
+
traversedDirection: direction,
|
|
938
|
+
weight: edge.weight ?? 1,
|
|
939
|
+
opinion: projectedOpinion,
|
|
940
|
+
operator: result.operator,
|
|
941
|
+
rationale: existingDispatch ? `${existingDispatch.rationale}; ${result.rationale}` : result.rationale,
|
|
942
|
+
hop: nextHop
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
async function loadCachedNode(scope, nodeId) {
|
|
946
|
+
const cacheKey = nodeIdToCacheKey(nodeId);
|
|
947
|
+
if (!scope.nodeCache.has(cacheKey)) {
|
|
948
|
+
scope.nodeCache.set(cacheKey, await scope.args.getNode(nodeId));
|
|
949
|
+
}
|
|
950
|
+
return scope.nodeCache.get(cacheKey) ?? null;
|
|
951
|
+
}
|
|
952
|
+
async function collectTargetDispatch(state, nextHop, spec, direction, edge, queue, scope) {
|
|
953
|
+
const sourceScope = scope.args.sourceScope;
|
|
954
|
+
if (sourceScope && !edgeMatchesWorkspaceReasoningScope(edge, sourceScope)) {
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
const targetNodeId = resolveTraversalTargetNodeId(edge, direction);
|
|
958
|
+
if (!targetNodeId) {
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
961
|
+
const targetNodeIdKey = nodeIdToCacheKey(targetNodeId);
|
|
962
|
+
if (state.visitedNodeIds.has(targetNodeIdKey)) {
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
const targetNode = await loadCachedNode(scope, targetNodeId);
|
|
966
|
+
if (targetNode?.nodeType !== "belief") {
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
if (sourceScope && !nodeMatchesWorkspaceReasoningScope(targetNode, sourceScope)) {
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
const targetOpinion = scope.opinionCache.get(targetNodeIdKey) ?? readNodeOpinion(targetNode);
|
|
973
|
+
const result = spec.operator(state.opinion, targetOpinion, edge, {
|
|
974
|
+
hop: nextHop,
|
|
975
|
+
sourceNodeId: state.nodeId,
|
|
976
|
+
targetNodeId,
|
|
977
|
+
traversedDirection: direction,
|
|
978
|
+
spec
|
|
979
|
+
});
|
|
980
|
+
if (!(result && hasProjectedOpinionChanged(targetOpinion, result.opinion))) {
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
const projectedOpinion = mkOpinion(
|
|
984
|
+
result.opinion.b,
|
|
985
|
+
result.opinion.d,
|
|
986
|
+
result.opinion.u,
|
|
987
|
+
result.opinion.a
|
|
988
|
+
);
|
|
989
|
+
scope.opinionCache.set(targetNodeIdKey, projectedOpinion);
|
|
990
|
+
const existingDispatch = scope.dispatchesByTargetId.get(targetNodeIdKey);
|
|
991
|
+
scope.dispatchesByTargetId.set(
|
|
992
|
+
targetNodeIdKey,
|
|
993
|
+
makeDispatchRecord(
|
|
994
|
+
targetNodeId,
|
|
995
|
+
spec,
|
|
996
|
+
direction,
|
|
997
|
+
edge,
|
|
998
|
+
projectedOpinion,
|
|
999
|
+
nextHop,
|
|
1000
|
+
result,
|
|
1001
|
+
existingDispatch
|
|
1002
|
+
)
|
|
1003
|
+
);
|
|
1004
|
+
if (canContinueTransitively2(spec, nextHop)) {
|
|
1005
|
+
queue.push(
|
|
1006
|
+
makeTransitiveState(state, targetNodeId, projectedOpinion, nextHop)
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
async function processTraversalSpec(state, nextHop, spec, queue, scope) {
|
|
1011
|
+
const sourceNodeId = state.nodeId;
|
|
1012
|
+
for (const direction of getTraversalDirections(spec.direction)) {
|
|
1013
|
+
const edges = await scope.args.queryEdges({
|
|
1014
|
+
nodeId: sourceNodeId,
|
|
1015
|
+
spec,
|
|
1016
|
+
direction,
|
|
1017
|
+
hop: nextHop
|
|
1018
|
+
});
|
|
1019
|
+
for (const edge of edges) {
|
|
1020
|
+
await collectTargetDispatch(
|
|
1021
|
+
state,
|
|
1022
|
+
nextHop,
|
|
1023
|
+
spec,
|
|
1024
|
+
direction,
|
|
1025
|
+
edge,
|
|
1026
|
+
queue,
|
|
1027
|
+
scope
|
|
1028
|
+
);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
async function processQueuedState(state, queue, scope) {
|
|
1033
|
+
const nextHop = state.hop + 1;
|
|
1034
|
+
for (const spec of scope.traversalSpecs) {
|
|
1035
|
+
if (!canTraverseHop2(spec, nextHop)) {
|
|
1036
|
+
continue;
|
|
1037
|
+
}
|
|
1038
|
+
await processTraversalSpec(state, nextHop, spec, queue, scope);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
function sortDispatches(dispatches) {
|
|
1042
|
+
return Array.from(dispatches).sort((left, right) => {
|
|
1043
|
+
if (left.hop !== right.hop) {
|
|
1044
|
+
return left.hop - right.hop;
|
|
1045
|
+
}
|
|
1046
|
+
return String(left.targetNodeId).localeCompare(String(right.targetNodeId));
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
954
1049
|
async function collectConfidencePropagationDispatches(args) {
|
|
955
1050
|
const dispatchesByTargetId = /* @__PURE__ */ new Map();
|
|
956
1051
|
const opinionCache = /* @__PURE__ */ new Map();
|
|
957
1052
|
const nodeCache = /* @__PURE__ */ new Map();
|
|
958
1053
|
const traversalSpecs = args.traversalSpecs ?? getEdgePropagationSpecs();
|
|
1054
|
+
const scope = {
|
|
1055
|
+
args,
|
|
1056
|
+
dispatchesByTargetId,
|
|
1057
|
+
opinionCache,
|
|
1058
|
+
nodeCache,
|
|
1059
|
+
traversalSpecs
|
|
1060
|
+
};
|
|
959
1061
|
const queue = [
|
|
960
|
-
|
|
961
|
-
nodeId: args.sourceNodeId,
|
|
962
|
-
opinion: args.sourceOpinion,
|
|
963
|
-
hop: 0,
|
|
964
|
-
visitedNodeIds: /* @__PURE__ */ new Set([String(args.sourceNodeId)])
|
|
965
|
-
}
|
|
1062
|
+
buildInitialState(args.sourceNodeId, args.sourceOpinion)
|
|
966
1063
|
];
|
|
967
|
-
const loadNode = async (nodeId) => {
|
|
968
|
-
const cacheKey = String(nodeId);
|
|
969
|
-
if (!nodeCache.has(cacheKey)) {
|
|
970
|
-
nodeCache.set(cacheKey, await args.getNode(nodeId));
|
|
971
|
-
}
|
|
972
|
-
return nodeCache.get(cacheKey) ?? null;
|
|
973
|
-
};
|
|
974
1064
|
while (queue.length > 0) {
|
|
975
1065
|
const state = queue.shift();
|
|
976
1066
|
if (!state) {
|
|
977
1067
|
continue;
|
|
978
1068
|
}
|
|
979
|
-
|
|
980
|
-
const nextHop = state.hop + 1;
|
|
981
|
-
if (!canTraverseHop(spec, nextHop)) {
|
|
982
|
-
continue;
|
|
983
|
-
}
|
|
984
|
-
for (const direction of getTraversalDirections(spec.direction)) {
|
|
985
|
-
const edges = await args.queryEdges({
|
|
986
|
-
nodeId: state.nodeId,
|
|
987
|
-
spec,
|
|
988
|
-
direction,
|
|
989
|
-
hop: nextHop
|
|
990
|
-
});
|
|
991
|
-
for (const edge of edges) {
|
|
992
|
-
if (args.sourceScope && !edgeMatchesWorkspaceReasoningScope(edge, args.sourceScope)) {
|
|
993
|
-
continue;
|
|
994
|
-
}
|
|
995
|
-
const targetNodeId = resolveTraversalTargetNodeId(edge, direction);
|
|
996
|
-
if (!targetNodeId) {
|
|
997
|
-
continue;
|
|
998
|
-
}
|
|
999
|
-
if (state.visitedNodeIds.has(String(targetNodeId))) {
|
|
1000
|
-
continue;
|
|
1001
|
-
}
|
|
1002
|
-
const targetNode = await loadNode(targetNodeId);
|
|
1003
|
-
if (!targetNode || targetNode.nodeType !== "belief") {
|
|
1004
|
-
continue;
|
|
1005
|
-
}
|
|
1006
|
-
if (args.sourceScope && !nodeMatchesWorkspaceReasoningScope(targetNode, args.sourceScope)) {
|
|
1007
|
-
continue;
|
|
1008
|
-
}
|
|
1009
|
-
const cacheKey = String(targetNodeId);
|
|
1010
|
-
const targetOpinion = opinionCache.get(cacheKey) ?? readNodeOpinion(targetNode);
|
|
1011
|
-
const result = spec.operator(state.opinion, targetOpinion, edge, {
|
|
1012
|
-
hop: nextHop,
|
|
1013
|
-
sourceNodeId: state.nodeId,
|
|
1014
|
-
targetNodeId,
|
|
1015
|
-
traversedDirection: direction,
|
|
1016
|
-
spec
|
|
1017
|
-
});
|
|
1018
|
-
if (!result || !hasProjectedOpinionChanged(targetOpinion, result.opinion)) {
|
|
1019
|
-
continue;
|
|
1020
|
-
}
|
|
1021
|
-
const projectedOpinion = mkOpinion(
|
|
1022
|
-
result.opinion.b,
|
|
1023
|
-
result.opinion.d,
|
|
1024
|
-
result.opinion.u,
|
|
1025
|
-
result.opinion.a
|
|
1026
|
-
);
|
|
1027
|
-
opinionCache.set(cacheKey, projectedOpinion);
|
|
1028
|
-
const existingDispatch = dispatchesByTargetId.get(cacheKey);
|
|
1029
|
-
dispatchesByTargetId.set(cacheKey, {
|
|
1030
|
-
targetNodeId,
|
|
1031
|
-
edgeType: spec.edgeType,
|
|
1032
|
-
traversedDirection: direction,
|
|
1033
|
-
weight: edge.weight ?? 1,
|
|
1034
|
-
opinion: projectedOpinion,
|
|
1035
|
-
operator: result.operator,
|
|
1036
|
-
rationale: existingDispatch ? `${existingDispatch.rationale}; ${result.rationale}` : result.rationale,
|
|
1037
|
-
hop: nextHop
|
|
1038
|
-
});
|
|
1039
|
-
if (canContinueTransitively(spec, nextHop)) {
|
|
1040
|
-
queue.push({
|
|
1041
|
-
nodeId: targetNodeId,
|
|
1042
|
-
opinion: projectedOpinion,
|
|
1043
|
-
hop: nextHop,
|
|
1044
|
-
visitedNodeIds: /* @__PURE__ */ new Set([
|
|
1045
|
-
...state.visitedNodeIds,
|
|
1046
|
-
String(targetNodeId)
|
|
1047
|
-
])
|
|
1048
|
-
});
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1069
|
+
await processQueuedState(state, queue, scope);
|
|
1053
1070
|
}
|
|
1054
|
-
return
|
|
1055
|
-
if (left.hop !== right.hop) {
|
|
1056
|
-
return left.hop - right.hop;
|
|
1057
|
-
}
|
|
1058
|
-
return String(left.targetNodeId).localeCompare(String(right.targetNodeId));
|
|
1059
|
-
});
|
|
1071
|
+
return sortDispatches(dispatchesByTargetId.values());
|
|
1060
1072
|
}
|
|
1061
1073
|
|
|
1062
1074
|
// src/epistemicBeliefs.confidence.ts
|
|
1075
|
+
function isRecord(value) {
|
|
1076
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1077
|
+
}
|
|
1078
|
+
function readConvexId(value) {
|
|
1079
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1080
|
+
}
|
|
1081
|
+
function readOptionalBoolean(value) {
|
|
1082
|
+
return typeof value === "boolean" ? value : void 0;
|
|
1083
|
+
}
|
|
1084
|
+
function readOptionalNumber(value) {
|
|
1085
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1086
|
+
}
|
|
1087
|
+
function readOptionalString(value) {
|
|
1088
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1089
|
+
}
|
|
1090
|
+
function readRecord(value) {
|
|
1091
|
+
return isRecord(value) ? value : void 0;
|
|
1092
|
+
}
|
|
1093
|
+
function readConfidenceBeliefNode(value) {
|
|
1094
|
+
if (!isRecord(value)) {
|
|
1095
|
+
return null;
|
|
1096
|
+
}
|
|
1097
|
+
const id = readConvexId(value._id);
|
|
1098
|
+
const nodeType = readOptionalString(value.nodeType);
|
|
1099
|
+
const projectId = readOptionalString(value.projectId);
|
|
1100
|
+
if (!(id && nodeType === "belief" && projectId)) {
|
|
1101
|
+
return null;
|
|
1102
|
+
}
|
|
1103
|
+
const node = {
|
|
1104
|
+
_id: id,
|
|
1105
|
+
nodeType,
|
|
1106
|
+
projectId
|
|
1107
|
+
};
|
|
1108
|
+
const confidence = readOptionalNumber(value.confidence);
|
|
1109
|
+
const epistemicLayer = readOptionalString(value.epistemicLayer);
|
|
1110
|
+
const globalId = readOptionalString(value.globalId);
|
|
1111
|
+
const metadata = readRecord(value.metadata);
|
|
1112
|
+
const opinionA = readOptionalNumber(value.opinion_a);
|
|
1113
|
+
const opinionB = readOptionalNumber(value.opinion_b);
|
|
1114
|
+
const opinionD = readOptionalNumber(value.opinion_d);
|
|
1115
|
+
const opinionU = readOptionalNumber(value.opinion_u);
|
|
1116
|
+
const predictionMeta = readRecord(value.predictionMeta);
|
|
1117
|
+
const publicationStatus = readOptionalString(value.publicationStatus);
|
|
1118
|
+
const status = readOptionalString(value.status);
|
|
1119
|
+
const tenantId = readOptionalString(value.tenantId);
|
|
1120
|
+
const topicId = readOptionalString(value.topicId);
|
|
1121
|
+
const tupleContradicted = readOptionalBoolean(value.tupleContradicted);
|
|
1122
|
+
const workspaceId = readOptionalString(value.workspaceId);
|
|
1123
|
+
if (confidence !== void 0) {
|
|
1124
|
+
node.confidence = confidence;
|
|
1125
|
+
}
|
|
1126
|
+
if (epistemicLayer !== void 0) {
|
|
1127
|
+
node.epistemicLayer = epistemicLayer;
|
|
1128
|
+
}
|
|
1129
|
+
if (globalId !== void 0) {
|
|
1130
|
+
node.globalId = globalId;
|
|
1131
|
+
}
|
|
1132
|
+
if (metadata !== void 0) {
|
|
1133
|
+
node.metadata = metadata;
|
|
1134
|
+
}
|
|
1135
|
+
if (opinionA !== void 0) {
|
|
1136
|
+
node.opinion_a = opinionA;
|
|
1137
|
+
}
|
|
1138
|
+
if (opinionB !== void 0) {
|
|
1139
|
+
node.opinion_b = opinionB;
|
|
1140
|
+
}
|
|
1141
|
+
if (opinionD !== void 0) {
|
|
1142
|
+
node.opinion_d = opinionD;
|
|
1143
|
+
}
|
|
1144
|
+
if (opinionU !== void 0) {
|
|
1145
|
+
node.opinion_u = opinionU;
|
|
1146
|
+
}
|
|
1147
|
+
if (predictionMeta !== void 0) {
|
|
1148
|
+
node.predictionMeta = predictionMeta;
|
|
1149
|
+
}
|
|
1150
|
+
if (publicationStatus !== void 0) {
|
|
1151
|
+
node.publicationStatus = publicationStatus;
|
|
1152
|
+
}
|
|
1153
|
+
if (status !== void 0) {
|
|
1154
|
+
node.status = status;
|
|
1155
|
+
}
|
|
1156
|
+
if (tenantId !== void 0) {
|
|
1157
|
+
node.tenantId = tenantId;
|
|
1158
|
+
}
|
|
1159
|
+
if (topicId !== void 0) {
|
|
1160
|
+
node.topicId = topicId;
|
|
1161
|
+
}
|
|
1162
|
+
if (tupleContradicted !== void 0) {
|
|
1163
|
+
node.tupleContradicted = tupleContradicted;
|
|
1164
|
+
}
|
|
1165
|
+
if (workspaceId !== void 0) {
|
|
1166
|
+
node.workspaceId = workspaceId;
|
|
1167
|
+
}
|
|
1168
|
+
return node;
|
|
1169
|
+
}
|
|
1170
|
+
function readPropagationEdge(value) {
|
|
1171
|
+
if (!isRecord(value)) {
|
|
1172
|
+
return null;
|
|
1173
|
+
}
|
|
1174
|
+
const edgeType = readOptionalString(value.edgeType);
|
|
1175
|
+
if (!edgeType) {
|
|
1176
|
+
return null;
|
|
1177
|
+
}
|
|
1178
|
+
const edge = { edgeType };
|
|
1179
|
+
const fromNodeId = readConvexId(value.fromNodeId);
|
|
1180
|
+
const tenantId = readOptionalString(value.tenantId);
|
|
1181
|
+
const toNodeId = readConvexId(value.toNodeId);
|
|
1182
|
+
const weight = readOptionalNumber(value.weight);
|
|
1183
|
+
const workspaceId = readOptionalString(value.workspaceId);
|
|
1184
|
+
if (fromNodeId !== void 0) {
|
|
1185
|
+
edge.fromNodeId = fromNodeId;
|
|
1186
|
+
}
|
|
1187
|
+
if (tenantId !== void 0) {
|
|
1188
|
+
edge.tenantId = tenantId;
|
|
1189
|
+
}
|
|
1190
|
+
if (toNodeId !== void 0) {
|
|
1191
|
+
edge.toNodeId = toNodeId;
|
|
1192
|
+
}
|
|
1193
|
+
if (weight !== void 0) {
|
|
1194
|
+
edge.weight = weight;
|
|
1195
|
+
}
|
|
1196
|
+
if (workspaceId !== void 0) {
|
|
1197
|
+
edge.workspaceId = workspaceId;
|
|
1198
|
+
}
|
|
1199
|
+
return edge;
|
|
1200
|
+
}
|
|
1201
|
+
function readRowList(values, reader) {
|
|
1202
|
+
return values.flatMap((value) => {
|
|
1203
|
+
const row = reader(value);
|
|
1204
|
+
return row ? [row] : [];
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1063
1207
|
async function applyBeliefConfidenceChange(ctx, args) {
|
|
1064
1208
|
const now = Date.now();
|
|
1065
|
-
const node = await ctx
|
|
1209
|
+
const node = await requireConfidenceBeliefNode(ctx, args);
|
|
1210
|
+
const state = await buildConfidenceChangeState(ctx, node, args);
|
|
1211
|
+
await assertConfidenceScoringPolicySatisfied(ctx, args, state);
|
|
1212
|
+
const tupleContradictionId = await createTupleContradictionIfNeeded(
|
|
1213
|
+
ctx,
|
|
1214
|
+
args,
|
|
1215
|
+
node,
|
|
1216
|
+
state
|
|
1217
|
+
);
|
|
1218
|
+
await patchBeliefConfidenceState(ctx, args, state);
|
|
1219
|
+
await scheduleFirstScoringThemeEdges(ctx, args, node, state);
|
|
1220
|
+
const beliefConfidenceId = await insertBeliefConfidenceRecord(
|
|
1221
|
+
ctx,
|
|
1222
|
+
args,
|
|
1223
|
+
state,
|
|
1224
|
+
tupleContradictionId,
|
|
1225
|
+
now
|
|
1226
|
+
);
|
|
1227
|
+
await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
|
|
1228
|
+
nodeId: args.nodeId,
|
|
1229
|
+
operation: "upsert"
|
|
1230
|
+
});
|
|
1231
|
+
await insertConfidenceAudit(
|
|
1232
|
+
ctx,
|
|
1233
|
+
args,
|
|
1234
|
+
node,
|
|
1235
|
+
state,
|
|
1236
|
+
tupleContradictionId,
|
|
1237
|
+
now
|
|
1238
|
+
);
|
|
1239
|
+
await insertTupleTransitionAuditIfNeeded(
|
|
1240
|
+
ctx,
|
|
1241
|
+
args,
|
|
1242
|
+
node,
|
|
1243
|
+
state,
|
|
1244
|
+
tupleContradictionId,
|
|
1245
|
+
now
|
|
1246
|
+
);
|
|
1247
|
+
await scheduleConfidenceFollowups(ctx, args, node, state);
|
|
1248
|
+
return {
|
|
1249
|
+
nodeId: args.nodeId,
|
|
1250
|
+
previousConfidence: state.previousConfidence,
|
|
1251
|
+
newConfidence: state.derivedConfidence,
|
|
1252
|
+
opinion: state.nextOpinion,
|
|
1253
|
+
beliefConfidenceId
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
async function requireConfidenceBeliefNode(ctx, args) {
|
|
1257
|
+
const node = readConfidenceBeliefNode(await ctx.db.get(args.nodeId));
|
|
1066
1258
|
if (!node) {
|
|
1067
1259
|
throwStructuredMutationError({
|
|
1068
1260
|
message: "Node not found.",
|
|
@@ -1073,59 +1265,28 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1073
1265
|
details: { nodeId: args.nodeId }
|
|
1074
1266
|
});
|
|
1075
1267
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
invariantCode: "entity.no_confidence",
|
|
1082
|
-
suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. appendSlScoring is for belief nodes only.",
|
|
1083
|
-
details: { nodeId: args.nodeId, nodeType: node.nodeType }
|
|
1084
|
-
});
|
|
1085
|
-
}
|
|
1086
|
-
if (!node.projectId) {
|
|
1087
|
-
throwStructuredMutationError({
|
|
1088
|
-
message: "Belief has no project scope.",
|
|
1089
|
-
status: 400,
|
|
1090
|
-
code: "MISSING_SCOPE",
|
|
1091
|
-
invariantCode: "belief.project_required",
|
|
1092
|
-
suggestion: "Belief must have a projectId before SL scoring can be appended.",
|
|
1093
|
-
details: { nodeId: args.nodeId }
|
|
1094
|
-
});
|
|
1095
|
-
}
|
|
1096
|
-
await requireProjectWriteAccess(
|
|
1097
|
-
ctx,
|
|
1098
|
-
node.projectId,
|
|
1099
|
-
args.authenticatedUserId
|
|
1100
|
-
);
|
|
1101
|
-
const existingMetadata = node.metadata || {};
|
|
1268
|
+
await requireScopeWriteAccess(ctx, node.projectId, args.authenticatedUserId);
|
|
1269
|
+
return node;
|
|
1270
|
+
}
|
|
1271
|
+
async function buildConfidenceChangeState(ctx, node, args) {
|
|
1272
|
+
const existingMetadata = readNodeMetadata(node);
|
|
1102
1273
|
const currentBeliefStatus = resolveBeliefStatus(node, existingMetadata);
|
|
1103
1274
|
const confidencePolicy = await getActiveConfidencePolicy(ctx);
|
|
1104
|
-
if (confidencePolicy.scoringMode === "after_worktree" && isPreValidationBeliefStatus(currentBeliefStatus)) {
|
|
1105
|
-
const hasCompletedWorktree = await hasCompletedWorktreeForBelief(
|
|
1106
|
-
ctx,
|
|
1107
|
-
args.nodeId
|
|
1108
|
-
);
|
|
1109
|
-
if (!hasCompletedWorktree) {
|
|
1110
|
-
throwStructuredMutationError({
|
|
1111
|
-
message: "Cannot score belief before worktree completion. Complete a worktree that tests this belief first.",
|
|
1112
|
-
status: 409,
|
|
1113
|
-
code: "CONFLICT",
|
|
1114
|
-
invariantCode: "belief.confidence_append_only",
|
|
1115
|
-
suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
|
|
1116
|
-
details: { nodeId: args.nodeId }
|
|
1117
|
-
});
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
1275
|
const previousConfidence = node.confidence || 0.5;
|
|
1121
1276
|
const predictionMeta = node.predictionMeta || existingMetadata.predictionMeta;
|
|
1122
1277
|
const previousOpinion = readBeliefOpinionSnapshot(node, existingMetadata);
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1278
|
+
const nextOpinion = {
|
|
1279
|
+
b: args.belief,
|
|
1280
|
+
d: args.disbelief,
|
|
1281
|
+
u: args.uncertainty,
|
|
1282
|
+
a: args.baseRate ?? 0.5
|
|
1283
|
+
};
|
|
1284
|
+
const derivedConfidence = confidenceFromSL(
|
|
1285
|
+
nextOpinion.b,
|
|
1286
|
+
nextOpinion.d,
|
|
1287
|
+
nextOpinion.u,
|
|
1288
|
+
nextOpinion.a
|
|
1289
|
+
);
|
|
1129
1290
|
const isFirstScoring = typeof node.confidence !== "number" || !Number.isFinite(node.confidence);
|
|
1130
1291
|
const previousTupleContradicted = readTupleContradictedFlag(node.tupleContradicted) ?? readTupleContradictedFlag(existingMetadata.tupleContradicted) ?? detectTupleContradiction(
|
|
1131
1292
|
previousOpinion,
|
|
@@ -1146,79 +1307,121 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1146
1307
|
predictionMeta,
|
|
1147
1308
|
metadata: existingMetadata
|
|
1148
1309
|
});
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1310
|
+
const storedRationale = args.rationale ?? `Confidence changed from ${previousConfidence.toFixed(2)} (nodeId: ${args.nodeId})`;
|
|
1311
|
+
return {
|
|
1312
|
+
confidencePolicy,
|
|
1313
|
+
currentBeliefStatus,
|
|
1314
|
+
derivedConfidence,
|
|
1315
|
+
existingMetadata,
|
|
1316
|
+
isFirstScoring,
|
|
1317
|
+
newBeliefStatus,
|
|
1318
|
+
nextOpinion,
|
|
1319
|
+
previousConfidence,
|
|
1320
|
+
previousTupleContradicted,
|
|
1321
|
+
storedRationale,
|
|
1322
|
+
tupleContradictionDescription,
|
|
1323
|
+
tupleTransition
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
function readNodeMetadata(node) {
|
|
1327
|
+
return node.metadata ?? {};
|
|
1328
|
+
}
|
|
1329
|
+
async function assertConfidenceScoringPolicySatisfied(ctx, args, state) {
|
|
1330
|
+
if (state.confidencePolicy.scoringMode !== "after_worktree" || !isPreValidationBeliefStatus(state.currentBeliefStatus)) {
|
|
1331
|
+
return;
|
|
1332
|
+
}
|
|
1333
|
+
const hasCompletedWorktree = await hasCompletedWorktreeForBelief(
|
|
1334
|
+
ctx,
|
|
1335
|
+
args.nodeId
|
|
1336
|
+
);
|
|
1337
|
+
if (hasCompletedWorktree) {
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1340
|
+
throwStructuredMutationError({
|
|
1341
|
+
message: "Cannot score belief before worktree completion. Complete a worktree that tests this belief first.",
|
|
1342
|
+
status: 409,
|
|
1343
|
+
code: "CONFLICT",
|
|
1344
|
+
invariantCode: "belief.confidence_append_only",
|
|
1345
|
+
suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
|
|
1346
|
+
details: { nodeId: args.nodeId }
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
async function createTupleContradictionIfNeeded(ctx, args, node, state) {
|
|
1350
|
+
if (!state.tupleTransition.crossedIntoTupleContradiction) {
|
|
1351
|
+
return;
|
|
1167
1352
|
}
|
|
1353
|
+
return await ctx.runMutation("contradictions:create", {
|
|
1354
|
+
projectId: node.projectId,
|
|
1355
|
+
topicId: node.topicId,
|
|
1356
|
+
beliefId: args.nodeId,
|
|
1357
|
+
beliefBId: args.nodeId,
|
|
1358
|
+
supportingInsightIds: [],
|
|
1359
|
+
contradictingInsightIds: [],
|
|
1360
|
+
severity: deriveTupleContradictionSeverity(node),
|
|
1361
|
+
source: "tuple_space",
|
|
1362
|
+
detectionMethod: "agent",
|
|
1363
|
+
description: state.tupleContradictionDescription,
|
|
1364
|
+
createdBy: args.authenticatedUserId
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1367
|
+
async function patchBeliefConfidenceState(ctx, args, state) {
|
|
1168
1368
|
await ctx.db.patch(args.nodeId, {
|
|
1169
|
-
confidence: derivedConfidence,
|
|
1170
|
-
beliefStatus: newBeliefStatus,
|
|
1171
|
-
tupleContradicted: tupleTransition.tupleContradicted,
|
|
1172
|
-
updatedAt: now,
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
opinion_a: slA,
|
|
1369
|
+
confidence: state.derivedConfidence,
|
|
1370
|
+
beliefStatus: state.newBeliefStatus,
|
|
1371
|
+
tupleContradicted: state.tupleTransition.tupleContradicted,
|
|
1372
|
+
updatedAt: Date.now(),
|
|
1373
|
+
opinion_b: state.nextOpinion.b,
|
|
1374
|
+
opinion_d: state.nextOpinion.d,
|
|
1375
|
+
opinion_u: state.nextOpinion.u,
|
|
1376
|
+
opinion_a: state.nextOpinion.a,
|
|
1178
1377
|
metadata: {
|
|
1179
|
-
...existingMetadata,
|
|
1180
|
-
beliefStatus: newBeliefStatus,
|
|
1181
|
-
slBelief:
|
|
1182
|
-
slDisbelief:
|
|
1183
|
-
slUncertainty:
|
|
1184
|
-
slBaseRate:
|
|
1185
|
-
tupleContradicted: tupleTransition.tupleContradicted
|
|
1378
|
+
...state.existingMetadata,
|
|
1379
|
+
beliefStatus: state.newBeliefStatus,
|
|
1380
|
+
slBelief: state.nextOpinion.b,
|
|
1381
|
+
slDisbelief: state.nextOpinion.d,
|
|
1382
|
+
slUncertainty: state.nextOpinion.u,
|
|
1383
|
+
slBaseRate: state.nextOpinion.a,
|
|
1384
|
+
tupleContradicted: state.tupleTransition.tupleContradicted
|
|
1186
1385
|
}
|
|
1187
1386
|
});
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
edgeType: "relates_to_thesis",
|
|
1201
|
-
weight: derivedConfidence,
|
|
1202
|
-
createdBy: args.authenticatedUserId,
|
|
1203
|
-
topicId: String(node.projectId),
|
|
1204
|
-
fromNodeType: "belief",
|
|
1205
|
-
toNodeType: "theme",
|
|
1206
|
-
fromLayer: "L3",
|
|
1207
|
-
toLayer: "L3"
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1387
|
+
}
|
|
1388
|
+
async function scheduleFirstScoringThemeEdges(ctx, args, node, state) {
|
|
1389
|
+
if (!state.isFirstScoring) {
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
const themeNodes = await ctx.db.query("epistemicNodes").withIndex(
|
|
1393
|
+
"by_topic",
|
|
1394
|
+
(q) => q.eq("topicId", node.topicId || node.projectId)
|
|
1395
|
+
).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
|
|
1396
|
+
for (const theme of themeNodes) {
|
|
1397
|
+
if (!(theme.globalId && node.globalId)) {
|
|
1398
|
+
continue;
|
|
1210
1399
|
}
|
|
1400
|
+
await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
|
|
1401
|
+
globalId: `edge-${node.globalId}-relates_to_thesis-${theme.globalId}`,
|
|
1402
|
+
fromGlobalId: node.globalId,
|
|
1403
|
+
toGlobalId: theme.globalId,
|
|
1404
|
+
edgeType: "relates_to_thesis",
|
|
1405
|
+
weight: state.derivedConfidence,
|
|
1406
|
+
createdBy: args.authenticatedUserId,
|
|
1407
|
+
topicId: String(node.projectId),
|
|
1408
|
+
fromNodeType: "belief",
|
|
1409
|
+
toNodeType: "theme",
|
|
1410
|
+
fromLayer: "L3",
|
|
1411
|
+
toLayer: "L3"
|
|
1412
|
+
});
|
|
1211
1413
|
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1414
|
+
}
|
|
1415
|
+
async function insertBeliefConfidenceRecord(ctx, args, state, tupleContradictionId, now) {
|
|
1416
|
+
return await ctx.db.insert("beliefConfidence", {
|
|
1214
1417
|
...buildBeliefConfidenceRow({
|
|
1215
1418
|
beliefId: args.nodeId,
|
|
1216
|
-
belief:
|
|
1217
|
-
disbelief:
|
|
1218
|
-
uncertainty:
|
|
1219
|
-
baseRate:
|
|
1419
|
+
belief: state.nextOpinion.b,
|
|
1420
|
+
disbelief: state.nextOpinion.d,
|
|
1421
|
+
uncertainty: state.nextOpinion.u,
|
|
1422
|
+
baseRate: state.nextOpinion.a,
|
|
1220
1423
|
trigger: args.trigger,
|
|
1221
|
-
rationale: storedRationale,
|
|
1424
|
+
rationale: state.storedRationale,
|
|
1222
1425
|
assessedBy: args.authenticatedUserId,
|
|
1223
1426
|
assessedAt: now,
|
|
1224
1427
|
slOperator: args.slOperator,
|
|
@@ -1227,25 +1430,23 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1227
1430
|
triggeringWorktreeId: args.triggeringWorktreeId
|
|
1228
1431
|
})
|
|
1229
1432
|
});
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
operation: "upsert"
|
|
1233
|
-
});
|
|
1433
|
+
}
|
|
1434
|
+
async function insertConfidenceAudit(ctx, args, node, state, tupleContradictionId, now) {
|
|
1234
1435
|
await ctx.db.insert("epistemicAudit", {
|
|
1235
1436
|
entityType: "belief",
|
|
1236
1437
|
entityId: args.nodeId,
|
|
1237
1438
|
changeType: "confidence_changed",
|
|
1238
1439
|
previousState: {
|
|
1239
|
-
confidence: previousConfidence,
|
|
1240
|
-
tupleContradicted: previousTupleContradicted
|
|
1440
|
+
confidence: state.previousConfidence,
|
|
1441
|
+
tupleContradicted: state.previousTupleContradicted
|
|
1241
1442
|
},
|
|
1242
1443
|
newState: {
|
|
1243
|
-
opinion: nextOpinion,
|
|
1244
|
-
confidence: derivedConfidence,
|
|
1444
|
+
opinion: state.nextOpinion,
|
|
1445
|
+
confidence: state.derivedConfidence,
|
|
1245
1446
|
trigger: args.trigger,
|
|
1246
|
-
rationale: storedRationale,
|
|
1247
|
-
tupleContradicted: tupleTransition.tupleContradicted,
|
|
1248
|
-
tupleContradictionPolicy: tupleTransition.policy,
|
|
1447
|
+
rationale: state.storedRationale,
|
|
1448
|
+
tupleContradicted: state.tupleTransition.tupleContradicted,
|
|
1449
|
+
tupleContradictionPolicy: state.tupleTransition.policy,
|
|
1249
1450
|
...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
|
|
1250
1451
|
},
|
|
1251
1452
|
changedBy: args.authenticatedUserId,
|
|
@@ -1254,28 +1455,39 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1254
1455
|
projectId: node.projectId,
|
|
1255
1456
|
topicId: node.topicId
|
|
1256
1457
|
});
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1458
|
+
}
|
|
1459
|
+
async function insertTupleTransitionAuditIfNeeded(ctx, args, node, state, tupleContradictionId, now) {
|
|
1460
|
+
if (!(state.tupleTransition.crossedIntoTupleContradiction || state.tupleTransition.crossedOutOfTupleContradiction)) {
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1463
|
+
await ctx.db.insert("epistemicAudit", {
|
|
1464
|
+
entityType: "belief",
|
|
1465
|
+
entityId: args.nodeId,
|
|
1466
|
+
changeType: "updated",
|
|
1467
|
+
previousState: { tupleContradicted: state.previousTupleContradicted },
|
|
1468
|
+
newState: {
|
|
1469
|
+
tupleContradicted: state.tupleTransition.tupleContradicted,
|
|
1470
|
+
action: state.tupleTransition.crossedIntoTupleContradiction ? "tuple_contradiction_detected" : "tuple_contradiction_cleared",
|
|
1471
|
+
opinion: state.nextOpinion,
|
|
1472
|
+
tupleContradictionPolicy: state.tupleTransition.policy,
|
|
1473
|
+
...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
|
|
1474
|
+
},
|
|
1475
|
+
rationale: tupleAuditRationale(state),
|
|
1476
|
+
changedBy: args.authenticatedUserId,
|
|
1477
|
+
isAgent: false,
|
|
1478
|
+
changedAt: now,
|
|
1479
|
+
projectId: node.projectId,
|
|
1480
|
+
topicId: node.topicId
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
function tupleAuditRationale(state) {
|
|
1484
|
+
if (state.tupleTransition.crossedIntoTupleContradiction) {
|
|
1485
|
+
return state.tupleContradictionDescription;
|
|
1277
1486
|
}
|
|
1278
|
-
|
|
1487
|
+
return `Tuple-space contradiction cleared: b=${state.nextOpinion.b.toFixed(2)}, d=${state.nextOpinion.d.toFixed(2)} no longer exceed the configured policy thresholds.`;
|
|
1488
|
+
}
|
|
1489
|
+
async function scheduleConfidenceFollowups(ctx, args, node, state) {
|
|
1490
|
+
if (Math.abs(state.derivedConfidence - state.previousConfidence) >= 0.15) {
|
|
1279
1491
|
await ctx.scheduler.runAfter(
|
|
1280
1492
|
5e3,
|
|
1281
1493
|
internal.bi.contradictionSemanticDetector.scanAffectedBeliefs,
|
|
@@ -1292,13 +1504,6 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1292
1504
|
{ nodeId: args.nodeId }
|
|
1293
1505
|
);
|
|
1294
1506
|
}
|
|
1295
|
-
return {
|
|
1296
|
-
nodeId: args.nodeId,
|
|
1297
|
-
previousConfidence,
|
|
1298
|
-
newConfidence: derivedConfidence,
|
|
1299
|
-
opinion: { b: slB, d: slD, u: slU, a: slA },
|
|
1300
|
-
beliefConfidenceId
|
|
1301
|
-
};
|
|
1302
1507
|
}
|
|
1303
1508
|
function propagationPressureLabel(edgeType, weight) {
|
|
1304
1509
|
if (edgeType === "contradicts" || edgeType === "refutes") {
|
|
@@ -1326,7 +1531,7 @@ internalMutation({
|
|
|
1326
1531
|
args.opinion_u,
|
|
1327
1532
|
args.opinion_a
|
|
1328
1533
|
);
|
|
1329
|
-
const sourceNode = await ctx.db.get(args.nodeId);
|
|
1534
|
+
const sourceNode = readConfidenceBeliefNode(await ctx.db.get(args.nodeId));
|
|
1330
1535
|
const sourceScope = await resolveNodeScopeForWorkspaceIsolation(
|
|
1331
1536
|
ctx,
|
|
1332
1537
|
sourceNode
|
|
@@ -1335,16 +1540,20 @@ internalMutation({
|
|
|
1335
1540
|
sourceNodeId: args.nodeId,
|
|
1336
1541
|
sourceOpinion,
|
|
1337
1542
|
sourceScope,
|
|
1338
|
-
queryEdges: async ({ nodeId, spec, direction }) =>
|
|
1339
|
-
|
|
1543
|
+
queryEdges: async ({ nodeId, spec, direction }) => readRowList(
|
|
1544
|
+
await ctx.db.query("epistemicEdges").withIndex(
|
|
1340
1545
|
direction === "outgoing" ? "by_from_type" : "by_to_type",
|
|
1341
1546
|
(q) => direction === "outgoing" ? q.eq("fromNodeId", nodeId).eq("edgeType", spec.edgeType) : q.eq("toNodeId", nodeId).eq("edgeType", spec.edgeType)
|
|
1342
|
-
).collect()
|
|
1343
|
-
|
|
1344
|
-
|
|
1547
|
+
).collect(),
|
|
1548
|
+
readPropagationEdge
|
|
1549
|
+
),
|
|
1550
|
+
getNode: async (nodeId) => readConfidenceBeliefNode(await ctx.db.get(nodeId))
|
|
1345
1551
|
});
|
|
1346
1552
|
for (const dispatch of dispatches) {
|
|
1347
|
-
const pressureLabel = propagationPressureLabel(
|
|
1553
|
+
const pressureLabel = propagationPressureLabel(
|
|
1554
|
+
dispatch.edgeType,
|
|
1555
|
+
dispatch.weight
|
|
1556
|
+
);
|
|
1348
1557
|
await applyBeliefConfidenceChange(ctx, {
|
|
1349
1558
|
nodeId: dispatch.targetNodeId,
|
|
1350
1559
|
belief: dispatch.opinion.b,
|
|
@@ -1374,9 +1583,7 @@ var ACTIVE_CONTRADICTION_STATUSES = /* @__PURE__ */ new Set([
|
|
|
1374
1583
|
"investigating",
|
|
1375
1584
|
"accepted_as_permanent"
|
|
1376
1585
|
]);
|
|
1377
|
-
var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
1378
|
-
"depends_on"
|
|
1379
|
-
]);
|
|
1586
|
+
var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set(["depends_on"]);
|
|
1380
1587
|
function classifyContradictionStatus(status) {
|
|
1381
1588
|
if (typeof status !== "string") {
|
|
1382
1589
|
return "active";
|
|
@@ -1389,6 +1596,99 @@ function classifyContradictionStatus(status) {
|
|
|
1389
1596
|
}
|
|
1390
1597
|
return "resolved";
|
|
1391
1598
|
}
|
|
1599
|
+
function isRecord2(value) {
|
|
1600
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1601
|
+
}
|
|
1602
|
+
function readOptionalNumber2(value) {
|
|
1603
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1604
|
+
}
|
|
1605
|
+
function readOptionalString2(value) {
|
|
1606
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1607
|
+
}
|
|
1608
|
+
function readConvexId2(value) {
|
|
1609
|
+
const normalized = readOptionalString2(value);
|
|
1610
|
+
return normalized;
|
|
1611
|
+
}
|
|
1612
|
+
function readMetricNodeDoc(value) {
|
|
1613
|
+
if (!isRecord2(value)) {
|
|
1614
|
+
return null;
|
|
1615
|
+
}
|
|
1616
|
+
const id = readConvexId2(value._id);
|
|
1617
|
+
const nodeType = readOptionalString2(value.nodeType);
|
|
1618
|
+
if (!(id && nodeType)) {
|
|
1619
|
+
return null;
|
|
1620
|
+
}
|
|
1621
|
+
const node = { _id: id, nodeType };
|
|
1622
|
+
const globalId = readOptionalString2(value.globalId);
|
|
1623
|
+
if (globalId !== void 0) {
|
|
1624
|
+
node.globalId = globalId;
|
|
1625
|
+
}
|
|
1626
|
+
if ("metadata" in value) {
|
|
1627
|
+
node.metadata = value.metadata;
|
|
1628
|
+
}
|
|
1629
|
+
const status = readOptionalString2(value.status);
|
|
1630
|
+
if (status !== void 0) {
|
|
1631
|
+
node.status = status;
|
|
1632
|
+
}
|
|
1633
|
+
return node;
|
|
1634
|
+
}
|
|
1635
|
+
function readIncomingEdgeRow(value) {
|
|
1636
|
+
if (!isRecord2(value)) {
|
|
1637
|
+
return null;
|
|
1638
|
+
}
|
|
1639
|
+
const fromNodeId = readOptionalString2(value.fromNodeId);
|
|
1640
|
+
if (!fromNodeId) {
|
|
1641
|
+
return null;
|
|
1642
|
+
}
|
|
1643
|
+
const edge = { fromNodeId };
|
|
1644
|
+
const id = readConvexId2(value._id);
|
|
1645
|
+
if (id !== void 0) {
|
|
1646
|
+
edge._id = id;
|
|
1647
|
+
}
|
|
1648
|
+
const edgeType = readOptionalString2(value.edgeType);
|
|
1649
|
+
if (edgeType !== void 0) {
|
|
1650
|
+
edge.edgeType = edgeType;
|
|
1651
|
+
}
|
|
1652
|
+
const fromGlobalId = readOptionalString2(value.fromGlobalId);
|
|
1653
|
+
if (fromGlobalId !== void 0) {
|
|
1654
|
+
edge.fromGlobalId = fromGlobalId;
|
|
1655
|
+
}
|
|
1656
|
+
const fromUuid = readOptionalString2(value.fromUuid);
|
|
1657
|
+
if (fromUuid !== void 0) {
|
|
1658
|
+
edge.fromUuid = fromUuid;
|
|
1659
|
+
}
|
|
1660
|
+
const sourceGlobalId = readOptionalString2(value.sourceGlobalId);
|
|
1661
|
+
if (sourceGlobalId !== void 0) {
|
|
1662
|
+
edge.sourceGlobalId = sourceGlobalId;
|
|
1663
|
+
}
|
|
1664
|
+
const targetGlobalId = readOptionalString2(value.targetGlobalId);
|
|
1665
|
+
if (targetGlobalId !== void 0) {
|
|
1666
|
+
edge.targetGlobalId = targetGlobalId;
|
|
1667
|
+
}
|
|
1668
|
+
const toGlobalId = readOptionalString2(value.toGlobalId);
|
|
1669
|
+
if (toGlobalId !== void 0) {
|
|
1670
|
+
edge.toGlobalId = toGlobalId;
|
|
1671
|
+
}
|
|
1672
|
+
const toNodeId = readOptionalString2(value.toNodeId);
|
|
1673
|
+
if (toNodeId !== void 0) {
|
|
1674
|
+
edge.toNodeId = toNodeId;
|
|
1675
|
+
}
|
|
1676
|
+
const toUuid = readOptionalString2(value.toUuid);
|
|
1677
|
+
if (toUuid !== void 0) {
|
|
1678
|
+
edge.toUuid = toUuid;
|
|
1679
|
+
}
|
|
1680
|
+
const weight = readOptionalNumber2(value.weight);
|
|
1681
|
+
if (weight !== void 0) {
|
|
1682
|
+
edge.weight = weight;
|
|
1683
|
+
}
|
|
1684
|
+
for (const timestampField of ["_creationTime", "createdAt", "updatedAt"]) {
|
|
1685
|
+
const timestamp = readOptionalNumber2(value[timestampField]);
|
|
1686
|
+
if (timestamp !== void 0) {
|
|
1687
|
+
edge[timestampField] = timestamp;
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
return edge;
|
|
1691
|
+
}
|
|
1392
1692
|
function getEdgeTimestamp(edge) {
|
|
1393
1693
|
if (typeof edge.updatedAt === "number") {
|
|
1394
1694
|
return edge.updatedAt;
|
|
@@ -1401,22 +1701,86 @@ function getEdgeTimestamp(edge) {
|
|
|
1401
1701
|
}
|
|
1402
1702
|
return null;
|
|
1403
1703
|
}
|
|
1704
|
+
async function collectNodeEndpointRefs(ctx, nodeId) {
|
|
1705
|
+
const refs = /* @__PURE__ */ new Set([String(nodeId)]);
|
|
1706
|
+
const node = readMetricNodeDoc(await ctx.db.get(nodeId));
|
|
1707
|
+
if (node?.globalId) {
|
|
1708
|
+
refs.add(node.globalId);
|
|
1709
|
+
}
|
|
1710
|
+
return [...refs];
|
|
1711
|
+
}
|
|
1712
|
+
async function collectIncomingEdgeRows(ctx, nodeId, edgeType) {
|
|
1713
|
+
const refs = await collectNodeEndpointRefs(ctx, nodeId);
|
|
1714
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1715
|
+
const edges = [];
|
|
1716
|
+
for (const ref of refs) {
|
|
1717
|
+
const rows = edgeType === void 0 ? await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", ref)).collect() : await ctx.db.query("epistemicEdges").withIndex(
|
|
1718
|
+
"by_to_type",
|
|
1719
|
+
(q) => q.eq("toNodeId", ref).eq("edgeType", edgeType)
|
|
1720
|
+
).collect();
|
|
1721
|
+
for (const row of rows) {
|
|
1722
|
+
const edge = readIncomingEdgeRow(row);
|
|
1723
|
+
if (!edge) {
|
|
1724
|
+
continue;
|
|
1725
|
+
}
|
|
1726
|
+
if (edgeType !== void 0 && edge.edgeType !== edgeType) {
|
|
1727
|
+
continue;
|
|
1728
|
+
}
|
|
1729
|
+
const key = edge._id === void 0 ? `${edge.fromNodeId}->${edge.toNodeId ?? ref}:${edge.edgeType ?? ""}` : String(edge._id);
|
|
1730
|
+
if (seen.has(key)) {
|
|
1731
|
+
continue;
|
|
1732
|
+
}
|
|
1733
|
+
seen.add(key);
|
|
1734
|
+
edges.push(edge);
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
return edges;
|
|
1738
|
+
}
|
|
1739
|
+
function sourceEndpointRefs(edge) {
|
|
1740
|
+
return [
|
|
1741
|
+
edge.fromNodeId,
|
|
1742
|
+
edge.sourceGlobalId,
|
|
1743
|
+
edge.fromGlobalId,
|
|
1744
|
+
edge.fromUuid
|
|
1745
|
+
].filter((value) => value !== void 0);
|
|
1746
|
+
}
|
|
1747
|
+
async function resolveEndpointNode(ctx, refs) {
|
|
1748
|
+
const candidates = refs.map((value) => value.trim()).filter(
|
|
1749
|
+
(value, index, values) => value.length > 0 && values.indexOf(value) === index
|
|
1750
|
+
);
|
|
1751
|
+
for (const candidate of candidates) {
|
|
1752
|
+
try {
|
|
1753
|
+
const direct = readMetricNodeDoc(
|
|
1754
|
+
await ctx.db.get(candidate)
|
|
1755
|
+
);
|
|
1756
|
+
if (direct) {
|
|
1757
|
+
return direct;
|
|
1758
|
+
}
|
|
1759
|
+
} catch {
|
|
1760
|
+
}
|
|
1761
|
+
const byGlobalId = readMetricNodeDoc(
|
|
1762
|
+
await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", candidate)).first()
|
|
1763
|
+
);
|
|
1764
|
+
if (byGlobalId) {
|
|
1765
|
+
return byGlobalId;
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
return null;
|
|
1769
|
+
}
|
|
1404
1770
|
async function getEvidenceLinks(ctx, beliefNodeId) {
|
|
1405
|
-
const edges = await ctx
|
|
1406
|
-
"by_to_type",
|
|
1407
|
-
(q) => q.eq("toNodeId", beliefNodeId).eq("edgeType", "informs")
|
|
1408
|
-
).collect();
|
|
1771
|
+
const edges = await collectIncomingEdgeRows(ctx, beliefNodeId, "informs");
|
|
1409
1772
|
if (edges.length === 0) {
|
|
1410
1773
|
return [];
|
|
1411
1774
|
}
|
|
1412
|
-
const
|
|
1413
|
-
|
|
1414
|
-
const node =
|
|
1415
|
-
if (
|
|
1416
|
-
|
|
1775
|
+
const links = [];
|
|
1776
|
+
for (const edge of edges) {
|
|
1777
|
+
const node = await resolveEndpointNode(ctx, sourceEndpointRefs(edge));
|
|
1778
|
+
if (node?.nodeType !== "evidence" || node.status === "archived") {
|
|
1779
|
+
continue;
|
|
1417
1780
|
}
|
|
1418
|
-
|
|
1419
|
-
}
|
|
1781
|
+
links.push({ edge, node });
|
|
1782
|
+
}
|
|
1783
|
+
return links;
|
|
1420
1784
|
}
|
|
1421
1785
|
function getEvidenceTags(node) {
|
|
1422
1786
|
const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : null;
|
|
@@ -1442,7 +1806,8 @@ async function computeTaggedEvidenceCount(args) {
|
|
|
1442
1806
|
};
|
|
1443
1807
|
}
|
|
1444
1808
|
async function computeContradictionCounts(ctx, beliefNodeId) {
|
|
1445
|
-
const
|
|
1809
|
+
const contradictionDb = ctx.db;
|
|
1810
|
+
const contradictions = await contradictionDb.query("contradictions").withIndex("by_beliefId", (q) => q.eq("beliefId", beliefNodeId)).collect();
|
|
1446
1811
|
return contradictions.reduce(
|
|
1447
1812
|
(counts, contradiction) => {
|
|
1448
1813
|
const status = contradiction.resolutionStatus ?? contradiction.status ?? "unresolved";
|
|
@@ -1478,18 +1843,16 @@ async function computeEvidenceFreshness(ctx, beliefNodeId, now = Date.now()) {
|
|
|
1478
1843
|
};
|
|
1479
1844
|
}
|
|
1480
1845
|
async function computeDependentBeliefCount(ctx, beliefNodeId) {
|
|
1481
|
-
const incomingEdges = await ctx
|
|
1846
|
+
const incomingEdges = await collectIncomingEdgeRows(ctx, beliefNodeId);
|
|
1482
1847
|
const dependencyEdges = incomingEdges.filter(
|
|
1483
|
-
(edge) => DEPENDENT_EDGE_TYPES.has(edge.edgeType)
|
|
1848
|
+
(edge) => edge.edgeType ? DEPENDENT_EDGE_TYPES.has(edge.edgeType) : false
|
|
1484
1849
|
);
|
|
1485
1850
|
if (dependencyEdges.length === 0) {
|
|
1486
1851
|
return 0;
|
|
1487
1852
|
}
|
|
1488
|
-
const dependentBeliefs = await Promise.all(
|
|
1489
|
-
dependencyEdges.map((edge) => ctx.db.get(edge.fromNodeId))
|
|
1490
|
-
);
|
|
1491
1853
|
const uniqueBeliefIds = /* @__PURE__ */ new Set();
|
|
1492
|
-
for (const
|
|
1854
|
+
for (const edge of dependencyEdges) {
|
|
1855
|
+
const node = await resolveEndpointNode(ctx, sourceEndpointRefs(edge));
|
|
1493
1856
|
if (node && node.nodeType === "belief" && node.status !== "archived" && node.status !== "deleted") {
|
|
1494
1857
|
uniqueBeliefIds.add(String(node._id));
|
|
1495
1858
|
}
|
|
@@ -1499,7 +1862,10 @@ async function computeDependentBeliefCount(ctx, beliefNodeId) {
|
|
|
1499
1862
|
async function snapshotEvidentialMetric(args) {
|
|
1500
1863
|
switch (args.metric) {
|
|
1501
1864
|
case "evidence_count": {
|
|
1502
|
-
const count = await computeEvidenceCountMetric(
|
|
1865
|
+
const count = await computeEvidenceCountMetric(
|
|
1866
|
+
args.ctx,
|
|
1867
|
+
args.beliefNodeId
|
|
1868
|
+
);
|
|
1503
1869
|
return {
|
|
1504
1870
|
metric: args.metric,
|
|
1505
1871
|
value: count,
|
|
@@ -1507,7 +1873,10 @@ async function snapshotEvidentialMetric(args) {
|
|
|
1507
1873
|
};
|
|
1508
1874
|
}
|
|
1509
1875
|
case "contradiction_status": {
|
|
1510
|
-
const counts = await computeContradictionCounts(
|
|
1876
|
+
const counts = await computeContradictionCounts(
|
|
1877
|
+
args.ctx,
|
|
1878
|
+
args.beliefNodeId
|
|
1879
|
+
);
|
|
1511
1880
|
return {
|
|
1512
1881
|
metric: args.metric,
|
|
1513
1882
|
value: counts.activeCount,
|
|
@@ -1527,7 +1896,10 @@ async function snapshotEvidentialMetric(args) {
|
|
|
1527
1896
|
};
|
|
1528
1897
|
}
|
|
1529
1898
|
case "dependent_count": {
|
|
1530
|
-
const count = await computeDependentBeliefCount(
|
|
1899
|
+
const count = await computeDependentBeliefCount(
|
|
1900
|
+
args.ctx,
|
|
1901
|
+
args.beliefNodeId
|
|
1902
|
+
);
|
|
1531
1903
|
return {
|
|
1532
1904
|
metric: args.metric,
|
|
1533
1905
|
value: count,
|
|
@@ -1543,7 +1915,9 @@ async function snapshotEvidentialMetric(args) {
|
|
|
1543
1915
|
}
|
|
1544
1916
|
}
|
|
1545
1917
|
async function evaluateBuiltInEvidentialContract(args) {
|
|
1546
|
-
const config = parseEvidentialEvaluatorConfig(
|
|
1918
|
+
const config = parseEvidentialEvaluatorConfig(
|
|
1919
|
+
args.contract.condition.evaluatorConfig
|
|
1920
|
+
);
|
|
1547
1921
|
const snapshot = await snapshotEvidentialMetric({
|
|
1548
1922
|
ctx: args.ctx,
|
|
1549
1923
|
beliefNodeId: args.belief._id,
|
|
@@ -1551,7 +1925,10 @@ async function evaluateBuiltInEvidentialContract(args) {
|
|
|
1551
1925
|
now: args.now
|
|
1552
1926
|
});
|
|
1553
1927
|
const comparisonSatisfied = snapshot.value !== null && compareMetricValue(config.operator, snapshot.value, config.threshold);
|
|
1554
|
-
const result =
|
|
1928
|
+
const result = resolveComparisonResult(
|
|
1929
|
+
args.contract.direction,
|
|
1930
|
+
comparisonSatisfied
|
|
1931
|
+
);
|
|
1555
1932
|
return {
|
|
1556
1933
|
result,
|
|
1557
1934
|
rationale: buildEvidentialRationale({
|
|
@@ -1571,57 +1948,66 @@ async function evaluateBuiltInEvidentialContract(args) {
|
|
|
1571
1948
|
}
|
|
1572
1949
|
};
|
|
1573
1950
|
}
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
"
|
|
1580
|
-
"
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1951
|
+
function evaluateMetricCheckerContract(args) {
|
|
1952
|
+
return Promise.resolve().then(() => {
|
|
1953
|
+
const config = parseMetricCheckerConfig(
|
|
1954
|
+
args.contract.condition.evaluatorConfig
|
|
1955
|
+
);
|
|
1956
|
+
const input = getEvaluatorInputRecord(args.inputData, "metricData");
|
|
1957
|
+
const metric = typeof input.metric === "string" && input.metric.length > 0 ? input.metric : config.metric;
|
|
1958
|
+
const observedValue = pickFiniteNumber(input, [
|
|
1959
|
+
"observedValue",
|
|
1960
|
+
"currentValue",
|
|
1961
|
+
"metricValue",
|
|
1962
|
+
"value"
|
|
1963
|
+
]) ?? config.observedValue ?? config.currentValue ?? config.metricValue ?? null;
|
|
1964
|
+
if (observedValue === null) {
|
|
1965
|
+
return {
|
|
1966
|
+
result: "inconclusive",
|
|
1967
|
+
rationale: `metric_checker is awaiting data for ${metric ?? args.contract.condition.expression}.`,
|
|
1968
|
+
data: {
|
|
1969
|
+
metric,
|
|
1970
|
+
observedValue: null,
|
|
1971
|
+
operator: config.operator,
|
|
1972
|
+
threshold: config.threshold,
|
|
1973
|
+
unit: config.unit
|
|
1974
|
+
}
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
const comparisonSatisfied = compareMetricValue(
|
|
1978
|
+
config.operator,
|
|
1979
|
+
observedValue,
|
|
1980
|
+
config.threshold
|
|
1981
|
+
);
|
|
1982
|
+
const result = resolveComparisonResult(
|
|
1983
|
+
args.contract.direction,
|
|
1984
|
+
comparisonSatisfied
|
|
1985
|
+
);
|
|
1585
1986
|
return {
|
|
1586
|
-
result
|
|
1587
|
-
rationale:
|
|
1987
|
+
result,
|
|
1988
|
+
rationale: buildComparisonRationale({
|
|
1989
|
+
label: metric ?? "metric",
|
|
1990
|
+
observedValue,
|
|
1991
|
+
operator: config.operator,
|
|
1992
|
+
threshold: config.threshold,
|
|
1993
|
+
comparisonSatisfied,
|
|
1994
|
+
result,
|
|
1995
|
+
unit: config.unit
|
|
1996
|
+
}),
|
|
1588
1997
|
data: {
|
|
1589
1998
|
metric,
|
|
1590
|
-
observedValue
|
|
1999
|
+
observedValue,
|
|
1591
2000
|
operator: config.operator,
|
|
1592
2001
|
threshold: config.threshold,
|
|
1593
2002
|
unit: config.unit
|
|
1594
2003
|
}
|
|
1595
2004
|
};
|
|
1596
|
-
}
|
|
1597
|
-
const comparisonSatisfied = compareMetricValue(
|
|
1598
|
-
config.operator,
|
|
1599
|
-
observedValue,
|
|
1600
|
-
config.threshold
|
|
1601
|
-
);
|
|
1602
|
-
const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
|
|
1603
|
-
return {
|
|
1604
|
-
result,
|
|
1605
|
-
rationale: buildComparisonRationale({
|
|
1606
|
-
label: metric ?? "metric",
|
|
1607
|
-
observedValue,
|
|
1608
|
-
operator: config.operator,
|
|
1609
|
-
threshold: config.threshold,
|
|
1610
|
-
comparisonSatisfied,
|
|
1611
|
-
result,
|
|
1612
|
-
unit: config.unit
|
|
1613
|
-
}),
|
|
1614
|
-
data: {
|
|
1615
|
-
metric,
|
|
1616
|
-
observedValue,
|
|
1617
|
-
operator: config.operator,
|
|
1618
|
-
threshold: config.threshold,
|
|
1619
|
-
unit: config.unit
|
|
1620
|
-
}
|
|
1621
|
-
};
|
|
2005
|
+
});
|
|
1622
2006
|
}
|
|
1623
2007
|
async function evaluateReferenceCheckCounterContract(args) {
|
|
1624
|
-
const config = parseReferenceCheckCounterConfig(
|
|
2008
|
+
const config = parseReferenceCheckCounterConfig(
|
|
2009
|
+
args.contract.condition.evaluatorConfig
|
|
2010
|
+
);
|
|
1625
2011
|
const input = getEvaluatorInputRecord(args.inputData, "referenceCheckData");
|
|
1626
2012
|
const tag = typeof input.tag === "string" && input.tag.trim().length > 0 ? input.tag.trim() : config.tag;
|
|
1627
2013
|
const snapshot = await computeTaggedEvidenceCount({
|
|
@@ -1635,7 +2021,10 @@ async function evaluateReferenceCheckCounterContract(args) {
|
|
|
1635
2021
|
snapshot.count,
|
|
1636
2022
|
config.threshold
|
|
1637
2023
|
);
|
|
1638
|
-
const result = resolveComparisonResult(
|
|
2024
|
+
const result = resolveComparisonResult(
|
|
2025
|
+
args.contract.direction,
|
|
2026
|
+
comparisonSatisfied
|
|
2027
|
+
);
|
|
1639
2028
|
return {
|
|
1640
2029
|
result,
|
|
1641
2030
|
rationale: buildComparisonRationale({
|
|
@@ -1657,130 +2046,167 @@ async function evaluateReferenceCheckCounterContract(args) {
|
|
|
1657
2046
|
}
|
|
1658
2047
|
};
|
|
1659
2048
|
}
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
"temporal_deadline requires contract.deadline to be set to a finite timestamp."
|
|
1664
|
-
);
|
|
1665
|
-
}
|
|
1666
|
-
const config = parseTemporalDeadlineConfig(args.contract.condition.evaluatorConfig);
|
|
1667
|
-
const input = getEvaluatorInputRecord(args.inputData, "temporalData");
|
|
1668
|
-
const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
|
|
1669
|
-
const completedAt = pickFiniteNumber(input, [
|
|
1670
|
-
"completedAt",
|
|
1671
|
-
"observedAt",
|
|
1672
|
-
"satisfiedAt",
|
|
1673
|
-
"achievedAt"
|
|
1674
|
-
]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
|
|
1675
|
-
const completed = input.completed === true || config.completed === true || completedAt !== void 0;
|
|
1676
|
-
if (completed) {
|
|
1677
|
-
if (completedAt !== void 0 && completedAt > args.contract.deadline) {
|
|
1678
|
-
return {
|
|
1679
|
-
result: "expired",
|
|
1680
|
-
rationale: `${label} completed at ${completedAt}, after deadline ${args.contract.deadline}.`,
|
|
1681
|
-
data: {
|
|
1682
|
-
label,
|
|
1683
|
-
deadline: args.contract.deadline,
|
|
1684
|
-
completed: true,
|
|
1685
|
-
completedAt,
|
|
1686
|
-
missedDeadline: true,
|
|
1687
|
-
overdueByMs: completedAt - args.contract.deadline
|
|
1688
|
-
}
|
|
1689
|
-
};
|
|
1690
|
-
}
|
|
1691
|
-
const result = args.contract.direction === "falsifies" ? "disconfirmed" : "confirmed";
|
|
2049
|
+
function resolveCompletedTemporalDeadlineResult(args) {
|
|
2050
|
+
const { completedAt, context, deadline, label } = args;
|
|
2051
|
+
if (completedAt !== void 0 && completedAt > deadline) {
|
|
1692
2052
|
return {
|
|
1693
|
-
result,
|
|
1694
|
-
rationale: `${label} completed
|
|
2053
|
+
result: "expired",
|
|
2054
|
+
rationale: `${label} completed at ${completedAt}, after deadline ${deadline}.`,
|
|
1695
2055
|
data: {
|
|
1696
2056
|
label,
|
|
1697
|
-
deadline
|
|
2057
|
+
deadline,
|
|
1698
2058
|
completed: true,
|
|
1699
|
-
completedAt
|
|
1700
|
-
missedDeadline:
|
|
2059
|
+
completedAt,
|
|
2060
|
+
missedDeadline: true,
|
|
2061
|
+
overdueByMs: completedAt - deadline
|
|
1701
2062
|
}
|
|
1702
2063
|
};
|
|
1703
2064
|
}
|
|
1704
|
-
|
|
2065
|
+
const result = context.contract.direction === "falsifies" ? "disconfirmed" : "confirmed";
|
|
2066
|
+
return {
|
|
2067
|
+
result,
|
|
2068
|
+
rationale: `${label} completed before deadline ${deadline}.`,
|
|
2069
|
+
data: {
|
|
2070
|
+
label,
|
|
2071
|
+
deadline,
|
|
2072
|
+
completed: true,
|
|
2073
|
+
completedAt: completedAt ?? null,
|
|
2074
|
+
missedDeadline: false
|
|
2075
|
+
}
|
|
2076
|
+
};
|
|
2077
|
+
}
|
|
2078
|
+
function resolveOpenTemporalDeadlineResult(args) {
|
|
2079
|
+
const { context, deadline, label } = args;
|
|
2080
|
+
if (context.now > deadline) {
|
|
1705
2081
|
return {
|
|
1706
2082
|
result: "expired",
|
|
1707
|
-
rationale: `${label} missed deadline ${
|
|
2083
|
+
rationale: `${label} missed deadline ${deadline}; temporal contract expired.`,
|
|
1708
2084
|
data: {
|
|
1709
2085
|
label,
|
|
1710
|
-
deadline
|
|
2086
|
+
deadline,
|
|
1711
2087
|
completed: false,
|
|
1712
|
-
overdueByMs:
|
|
2088
|
+
overdueByMs: context.now - deadline
|
|
1713
2089
|
}
|
|
1714
2090
|
};
|
|
1715
2091
|
}
|
|
1716
2092
|
return {
|
|
1717
2093
|
result: "inconclusive",
|
|
1718
|
-
rationale: `${label} is still before deadline ${
|
|
2094
|
+
rationale: `${label} is still before deadline ${deadline}; awaiting outcome.`,
|
|
1719
2095
|
data: {
|
|
1720
2096
|
label,
|
|
1721
|
-
deadline
|
|
2097
|
+
deadline,
|
|
1722
2098
|
completed: false,
|
|
1723
|
-
timeRemainingMs:
|
|
2099
|
+
timeRemainingMs: deadline - context.now
|
|
1724
2100
|
}
|
|
1725
2101
|
};
|
|
1726
2102
|
}
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
2103
|
+
function evaluateTemporalDeadlineContract(args) {
|
|
2104
|
+
return Promise.resolve().then(() => {
|
|
2105
|
+
if (typeof args.contract.deadline !== "number" || !Number.isFinite(args.contract.deadline)) {
|
|
2106
|
+
throw new Error(
|
|
2107
|
+
"temporal_deadline requires contract.deadline to be set to a finite timestamp."
|
|
2108
|
+
);
|
|
2109
|
+
}
|
|
2110
|
+
const deadline = args.contract.deadline;
|
|
2111
|
+
const config = parseTemporalDeadlineConfig(
|
|
2112
|
+
args.contract.condition.evaluatorConfig
|
|
2113
|
+
);
|
|
2114
|
+
const input = getEvaluatorInputRecord(args.inputData, "temporalData");
|
|
2115
|
+
const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
|
|
2116
|
+
const completedAt = pickFiniteNumber(input, [
|
|
2117
|
+
"completedAt",
|
|
2118
|
+
"observedAt",
|
|
2119
|
+
"satisfiedAt",
|
|
2120
|
+
"achievedAt"
|
|
2121
|
+
]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
|
|
2122
|
+
const completed = input.completed === true || config.completed === true || completedAt !== void 0;
|
|
2123
|
+
if (completed) {
|
|
2124
|
+
return resolveCompletedTemporalDeadlineResult({
|
|
2125
|
+
completedAt,
|
|
2126
|
+
context: args,
|
|
2127
|
+
deadline,
|
|
2128
|
+
label
|
|
2129
|
+
});
|
|
2130
|
+
}
|
|
2131
|
+
return resolveOpenTemporalDeadlineResult({
|
|
2132
|
+
context: args,
|
|
2133
|
+
deadline,
|
|
2134
|
+
label
|
|
2135
|
+
});
|
|
2136
|
+
});
|
|
2137
|
+
}
|
|
2138
|
+
function evaluateMarketIndexComparatorContract(args) {
|
|
2139
|
+
return Promise.resolve().then(() => {
|
|
2140
|
+
const config = parseMarketIndexComparatorConfig(
|
|
2141
|
+
args.contract.condition.evaluatorConfig
|
|
2142
|
+
);
|
|
2143
|
+
const input = getEvaluatorInputRecord(args.inputData, "marketIndexData");
|
|
2144
|
+
const subject = typeof input.subject === "string" && input.subject.length > 0 ? input.subject : config.subject;
|
|
2145
|
+
const benchmark = typeof input.benchmark === "string" && input.benchmark.length > 0 ? input.benchmark : config.benchmark;
|
|
2146
|
+
const subjectValue = pickFiniteNumber(input, ["subjectValue", "primaryValue", "leftValue"]) ?? config.subjectValue ?? config.primaryValue ?? null;
|
|
2147
|
+
const benchmarkValue = pickFiniteNumber(input, [
|
|
2148
|
+
"benchmarkValue",
|
|
2149
|
+
"comparisonValue",
|
|
2150
|
+
"rightValue"
|
|
2151
|
+
]) ?? config.benchmarkValue ?? config.comparisonValue ?? null;
|
|
2152
|
+
if (subjectValue === null || benchmarkValue === null) {
|
|
2153
|
+
return {
|
|
2154
|
+
result: "inconclusive",
|
|
2155
|
+
rationale: "market_index_comparator is awaiting both subject and benchmark values.",
|
|
2156
|
+
data: {
|
|
2157
|
+
subject,
|
|
2158
|
+
subjectValue,
|
|
2159
|
+
benchmark,
|
|
2160
|
+
benchmarkValue,
|
|
2161
|
+
operator: config.operator,
|
|
2162
|
+
threshold: config.threshold
|
|
2163
|
+
}
|
|
2164
|
+
};
|
|
2165
|
+
}
|
|
2166
|
+
if (benchmarkValue === 0) {
|
|
2167
|
+
throw new Error(
|
|
2168
|
+
"market_index_comparator cannot compare against a zero benchmark value."
|
|
2169
|
+
);
|
|
2170
|
+
}
|
|
2171
|
+
const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
|
|
2172
|
+
const comparisonSatisfied = compareMetricValue(
|
|
2173
|
+
config.operator,
|
|
2174
|
+
differentialPercent,
|
|
2175
|
+
config.threshold
|
|
2176
|
+
);
|
|
2177
|
+
const result = resolveComparisonResult(
|
|
2178
|
+
args.contract.direction,
|
|
2179
|
+
comparisonSatisfied
|
|
2180
|
+
);
|
|
1735
2181
|
return {
|
|
1736
|
-
result
|
|
1737
|
-
rationale:
|
|
2182
|
+
result,
|
|
2183
|
+
rationale: buildComparisonRationale({
|
|
2184
|
+
label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
|
|
2185
|
+
observedValue: differentialPercent,
|
|
2186
|
+
operator: config.operator,
|
|
2187
|
+
threshold: config.threshold,
|
|
2188
|
+
comparisonSatisfied,
|
|
2189
|
+
result,
|
|
2190
|
+
unit: "%"
|
|
2191
|
+
}),
|
|
1738
2192
|
data: {
|
|
1739
2193
|
subject,
|
|
1740
2194
|
subjectValue,
|
|
1741
2195
|
benchmark,
|
|
1742
2196
|
benchmarkValue,
|
|
2197
|
+
differentialPercent,
|
|
1743
2198
|
operator: config.operator,
|
|
1744
2199
|
threshold: config.threshold
|
|
1745
2200
|
}
|
|
1746
2201
|
};
|
|
1747
|
-
}
|
|
1748
|
-
if (benchmarkValue === 0) {
|
|
1749
|
-
throw new Error(
|
|
1750
|
-
"market_index_comparator cannot compare against a zero benchmark value."
|
|
1751
|
-
);
|
|
1752
|
-
}
|
|
1753
|
-
const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
|
|
1754
|
-
const comparisonSatisfied = compareMetricValue(
|
|
1755
|
-
config.operator,
|
|
1756
|
-
differentialPercent,
|
|
1757
|
-
config.threshold
|
|
1758
|
-
);
|
|
1759
|
-
const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
|
|
1760
|
-
return {
|
|
1761
|
-
result,
|
|
1762
|
-
rationale: buildComparisonRationale({
|
|
1763
|
-
label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
|
|
1764
|
-
observedValue: differentialPercent,
|
|
1765
|
-
operator: config.operator,
|
|
1766
|
-
threshold: config.threshold,
|
|
1767
|
-
comparisonSatisfied,
|
|
1768
|
-
result,
|
|
1769
|
-
unit: "%"
|
|
1770
|
-
}),
|
|
1771
|
-
data: {
|
|
1772
|
-
subject,
|
|
1773
|
-
subjectValue,
|
|
1774
|
-
benchmark,
|
|
1775
|
-
benchmarkValue,
|
|
1776
|
-
differentialPercent,
|
|
1777
|
-
operator: config.operator,
|
|
1778
|
-
threshold: config.threshold
|
|
1779
|
-
}
|
|
1780
|
-
};
|
|
2202
|
+
});
|
|
1781
2203
|
}
|
|
1782
2204
|
var METRIC_COMPARATOR_EVALUATOR_NAMES = {
|
|
1783
|
-
evidentialAliases: /* @__PURE__ */ new Set([
|
|
2205
|
+
evidentialAliases: /* @__PURE__ */ new Set([
|
|
2206
|
+
"evidential",
|
|
2207
|
+
"built_in_evidential",
|
|
2208
|
+
"builtin_evidential"
|
|
2209
|
+
]),
|
|
1784
2210
|
metricChecker: "metric_checker",
|
|
1785
2211
|
referenceCheckCounter: "reference_check_counter",
|
|
1786
2212
|
temporalDeadline: "temporal_deadline",
|
|
@@ -1788,6 +2214,8 @@ var METRIC_COMPARATOR_EVALUATOR_NAMES = {
|
|
|
1788
2214
|
};
|
|
1789
2215
|
|
|
1790
2216
|
// src/evaluators/shared.ts
|
|
2217
|
+
var WINDOWS_PATH_SEPARATORS = /\\/g;
|
|
2218
|
+
var LEADING_DOT_SLASH = /^\.\//;
|
|
1791
2219
|
function asArray(value) {
|
|
1792
2220
|
return Array.isArray(value) ? value : [];
|
|
1793
2221
|
}
|
|
@@ -1829,7 +2257,7 @@ function extractTextCandidates(value) {
|
|
|
1829
2257
|
return Array.from(new Set(candidates));
|
|
1830
2258
|
}
|
|
1831
2259
|
function normalizeFilePath(value) {
|
|
1832
|
-
return value.replace(
|
|
2260
|
+
return value.replace(WINDOWS_PATH_SEPARATORS, "/").replace(LEADING_DOT_SLASH, "");
|
|
1833
2261
|
}
|
|
1834
2262
|
function normalizeToolResultEnvelope(value) {
|
|
1835
2263
|
const record = asRecord(value);
|
|
@@ -1883,7 +2311,7 @@ function somePatternMatches(filePath, patterns) {
|
|
|
1883
2311
|
return patterns.some((pattern) => patternMatchesPath(filePath, pattern));
|
|
1884
2312
|
}
|
|
1885
2313
|
|
|
1886
|
-
// src/evaluators/
|
|
2314
|
+
// src/evaluators/lint-checker-evaluator.ts
|
|
1887
2315
|
function parseConfig(condition) {
|
|
1888
2316
|
const record = asRecord(condition.evaluatorConfig);
|
|
1889
2317
|
if (!record) {
|
|
@@ -1955,7 +2383,10 @@ var lintCheckerEvaluator = {
|
|
|
1955
2383
|
}
|
|
1956
2384
|
const envelope = normalizeToolResultEnvelope(args.resultData);
|
|
1957
2385
|
const exitCode = asNumber(envelope.exitCode);
|
|
1958
|
-
const matchedDiagnostics = getMatchedDiagnostics(
|
|
2386
|
+
const matchedDiagnostics = getMatchedDiagnostics(
|
|
2387
|
+
args.contract,
|
|
2388
|
+
args.resultData
|
|
2389
|
+
);
|
|
1959
2390
|
if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
|
|
1960
2391
|
return {
|
|
1961
2392
|
result: "inconclusive",
|
|
@@ -1981,7 +2412,7 @@ var lintCheckerEvaluator = {
|
|
|
1981
2412
|
}
|
|
1982
2413
|
};
|
|
1983
2414
|
|
|
1984
|
-
// src/evaluators/
|
|
2415
|
+
// src/evaluators/sentry-checker-evaluator.ts
|
|
1985
2416
|
function parseConfig2(condition) {
|
|
1986
2417
|
const record = asRecord(condition.evaluatorConfig);
|
|
1987
2418
|
if (!record) {
|
|
@@ -2066,7 +2497,7 @@ var sentryCheckerEvaluator = {
|
|
|
2066
2497
|
}
|
|
2067
2498
|
};
|
|
2068
2499
|
|
|
2069
|
-
// src/evaluators/
|
|
2500
|
+
// src/evaluators/test-runner-evaluator.ts
|
|
2070
2501
|
function parseConfig3(condition) {
|
|
2071
2502
|
const record = asRecord(condition.evaluatorConfig);
|
|
2072
2503
|
if (!record) {
|
|
@@ -2212,7 +2643,7 @@ var testRunnerEvaluator = {
|
|
|
2212
2643
|
}
|
|
2213
2644
|
};
|
|
2214
2645
|
|
|
2215
|
-
// src/evaluators/
|
|
2646
|
+
// src/evaluators/tsc-checker-evaluator.ts
|
|
2216
2647
|
function parseConfig4(condition) {
|
|
2217
2648
|
const record = asRecord(condition.evaluatorConfig);
|
|
2218
2649
|
if (!record) {
|
|
@@ -2297,7 +2728,10 @@ var tscCheckerEvaluator = {
|
|
|
2297
2728
|
}
|
|
2298
2729
|
const envelope = normalizeToolResultEnvelope(args.resultData);
|
|
2299
2730
|
const exitCode = asNumber(envelope.exitCode);
|
|
2300
|
-
const matchedDiagnostics = getMatchedDiagnostics2(
|
|
2731
|
+
const matchedDiagnostics = getMatchedDiagnostics2(
|
|
2732
|
+
args.contract,
|
|
2733
|
+
args.resultData
|
|
2734
|
+
);
|
|
2301
2735
|
if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
|
|
2302
2736
|
return {
|
|
2303
2737
|
result: "inconclusive",
|
|
@@ -2346,6 +2780,18 @@ var BUILT_IN_REFERENCE_CHECK_COUNTER2 = METRIC_COMPARATOR_EVALUATOR_NAMES.refere
|
|
|
2346
2780
|
var BUILT_IN_TEMPORAL_DEADLINE2 = METRIC_COMPARATOR_EVALUATOR_NAMES.temporalDeadline;
|
|
2347
2781
|
var BUILT_IN_MARKET_INDEX_COMPARATOR2 = METRIC_COMPARATOR_EVALUATOR_NAMES.marketIndexComparator;
|
|
2348
2782
|
var MAX_CONTRACT_EVALUATION_BATCH_SIZE = 50;
|
|
2783
|
+
function confidenceSeed(args) {
|
|
2784
|
+
if (typeof args.currentConfidence === "number") {
|
|
2785
|
+
return args.currentConfidence;
|
|
2786
|
+
}
|
|
2787
|
+
if (typeof args.beliefConfidence === "number") {
|
|
2788
|
+
return args.beliefConfidence;
|
|
2789
|
+
}
|
|
2790
|
+
return 0.5;
|
|
2791
|
+
}
|
|
2792
|
+
function contractDocId(contract) {
|
|
2793
|
+
return contract._id;
|
|
2794
|
+
}
|
|
2349
2795
|
function clearEpistemicEvaluators() {
|
|
2350
2796
|
evaluatorRegistry.clear();
|
|
2351
2797
|
ensureBuiltInEvaluators();
|
|
@@ -2438,7 +2884,10 @@ async function executeContractEvaluation(args) {
|
|
|
2438
2884
|
rationale: `No epistemic evaluator registered for "${args.contract.condition.evaluator}".`
|
|
2439
2885
|
};
|
|
2440
2886
|
}
|
|
2441
|
-
const confidenceBefore =
|
|
2887
|
+
const confidenceBefore = confidenceSeed({
|
|
2888
|
+
beliefConfidence: args.belief.confidence,
|
|
2889
|
+
currentConfidence: args.currentConfidence
|
|
2890
|
+
});
|
|
2442
2891
|
const modulationPlan = deriveContractModulationPlan({
|
|
2443
2892
|
currentConfidence: confidenceBefore,
|
|
2444
2893
|
modulation: args.contract.modulation,
|
|
@@ -2478,16 +2927,16 @@ async function executeContractEvaluation(args) {
|
|
|
2478
2927
|
modulationRationale: evaluation.rationale,
|
|
2479
2928
|
topicId: args.contract.topicId
|
|
2480
2929
|
});
|
|
2481
|
-
const nextStatus = deriveContractStatus(
|
|
2482
|
-
|
|
2483
|
-
args.contract.
|
|
2484
|
-
{
|
|
2485
|
-
status: nextStatus,
|
|
2486
|
-
lastEvaluatedAt: args.now,
|
|
2487
|
-
evaluationCount: (args.contract.evaluationCount ?? 0) + 1,
|
|
2488
|
-
updatedAt: args.now
|
|
2489
|
-
}
|
|
2930
|
+
const nextStatus = deriveContractStatus(
|
|
2931
|
+
evaluation.result,
|
|
2932
|
+
args.contract.status
|
|
2490
2933
|
);
|
|
2934
|
+
await args.ctx.db.patch(contractDocId(args.contract), {
|
|
2935
|
+
status: nextStatus,
|
|
2936
|
+
lastEvaluatedAt: args.now,
|
|
2937
|
+
evaluationCount: (args.contract.evaluationCount ?? 0) + 1,
|
|
2938
|
+
updatedAt: args.now
|
|
2939
|
+
});
|
|
2491
2940
|
return {
|
|
2492
2941
|
evaluationId,
|
|
2493
2942
|
result: evaluation.result,
|
|
@@ -2572,7 +3021,8 @@ async function evaluateContractsForTriggerBatch(args) {
|
|
|
2572
3021
|
};
|
|
2573
3022
|
}
|
|
2574
3023
|
async function loadContractsForBelief(args) {
|
|
2575
|
-
|
|
3024
|
+
const rows = await args.ctx.db.query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
|
|
3025
|
+
return rows;
|
|
2576
3026
|
}
|
|
2577
3027
|
async function loadContractsForTrigger(args) {
|
|
2578
3028
|
const contracts = await loadContractsForBelief(args);
|
|
@@ -2607,6 +3057,24 @@ function resolveSchedulesForTrigger2(trigger) {
|
|
|
2607
3057
|
}
|
|
2608
3058
|
return /* @__PURE__ */ new Set(["event_driven"]);
|
|
2609
3059
|
}
|
|
3060
|
+
function contractTables(ctx) {
|
|
3061
|
+
return ctx.db;
|
|
3062
|
+
}
|
|
3063
|
+
function assertBeliefNode(value, message = "Belief not found.") {
|
|
3064
|
+
if (!value || typeof value !== "object" || value.nodeType !== "belief") {
|
|
3065
|
+
throw new Error(message);
|
|
3066
|
+
}
|
|
3067
|
+
return value;
|
|
3068
|
+
}
|
|
3069
|
+
function normalizeEngineeringTrigger(trigger) {
|
|
3070
|
+
if (trigger === "manual") {
|
|
3071
|
+
return "manual";
|
|
3072
|
+
}
|
|
3073
|
+
if (trigger === "evidence_added") {
|
|
3074
|
+
return "evidence_added";
|
|
3075
|
+
}
|
|
3076
|
+
return trigger;
|
|
3077
|
+
}
|
|
2610
3078
|
async function requireAuth(ctx) {
|
|
2611
3079
|
const userId = await getCurrentUserId(ctx);
|
|
2612
3080
|
if (!userId) {
|
|
@@ -2642,17 +3110,21 @@ async function requireTopicReadAccess(ctx, beliefs, userId) {
|
|
|
2642
3110
|
projectIds.add(belief.projectId);
|
|
2643
3111
|
}
|
|
2644
3112
|
for (const projectId of projectIds) {
|
|
2645
|
-
const hasAccess = await checkProjectAccess(
|
|
3113
|
+
const hasAccess = await checkProjectAccess(
|
|
3114
|
+
ctx,
|
|
3115
|
+
projectId,
|
|
3116
|
+
userId
|
|
3117
|
+
);
|
|
2646
3118
|
if (!hasAccess) {
|
|
2647
3119
|
throw new Error("Project access required.");
|
|
2648
3120
|
}
|
|
2649
3121
|
}
|
|
2650
3122
|
}
|
|
2651
3123
|
async function getContractByContractId(ctx, contractId) {
|
|
2652
|
-
return await ctx.
|
|
3124
|
+
return await contractTables(ctx).query("epistemicContracts").withIndex("by_contractId", (q) => q.eq("contractId", contractId)).first();
|
|
2653
3125
|
}
|
|
2654
3126
|
async function getLatestEvaluation(ctx, contractId) {
|
|
2655
|
-
const evaluations = await ctx.
|
|
3127
|
+
const evaluations = await contractTables(ctx).query("contractEvaluations").withIndex("by_contract_time", (q) => q.eq("contractId", contractId)).order("desc").take(1);
|
|
2656
3128
|
return evaluations[0] ?? null;
|
|
2657
3129
|
}
|
|
2658
3130
|
var evaluateEvidenceCount = query({
|
|
@@ -2662,10 +3134,7 @@ var evaluateEvidenceCount = query({
|
|
|
2662
3134
|
returns: permissiveReturn,
|
|
2663
3135
|
handler: async (ctx, args) => {
|
|
2664
3136
|
const userId = await requireAuth(ctx);
|
|
2665
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2666
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2667
|
-
throw new Error("Belief not found.");
|
|
2668
|
-
}
|
|
3137
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2669
3138
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2670
3139
|
return await computeEvidenceCountMetric(ctx, args.beliefNodeId);
|
|
2671
3140
|
}
|
|
@@ -2677,10 +3146,7 @@ var evaluateContradictionStatus = query({
|
|
|
2677
3146
|
returns: permissiveReturn,
|
|
2678
3147
|
handler: async (ctx, args) => {
|
|
2679
3148
|
const userId = await requireAuth(ctx);
|
|
2680
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2681
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2682
|
-
throw new Error("Belief not found.");
|
|
2683
|
-
}
|
|
3149
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2684
3150
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2685
3151
|
return await computeContradictionCounts(ctx, args.beliefNodeId);
|
|
2686
3152
|
}
|
|
@@ -2692,10 +3158,7 @@ var evaluateEdgeFreshness = query({
|
|
|
2692
3158
|
returns: permissiveReturn,
|
|
2693
3159
|
handler: async (ctx, args) => {
|
|
2694
3160
|
const userId = await requireAuth(ctx);
|
|
2695
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2696
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2697
|
-
throw new Error("Belief not found.");
|
|
2698
|
-
}
|
|
3161
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2699
3162
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2700
3163
|
return await computeEvidenceFreshness(ctx, args.beliefNodeId);
|
|
2701
3164
|
}
|
|
@@ -2707,10 +3170,7 @@ var evaluateDependentBeliefCount = query({
|
|
|
2707
3170
|
returns: permissiveReturn,
|
|
2708
3171
|
handler: async (ctx, args) => {
|
|
2709
3172
|
const userId = await requireAuth(ctx);
|
|
2710
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2711
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2712
|
-
throw new Error("Belief not found.");
|
|
2713
|
-
}
|
|
3173
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2714
3174
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2715
3175
|
return await computeDependentBeliefCount(ctx, args.beliefNodeId);
|
|
2716
3176
|
}
|
|
@@ -2774,10 +3234,7 @@ var createEpistemicContract = mutation({
|
|
|
2774
3234
|
ctx,
|
|
2775
3235
|
args.authenticatedUserId
|
|
2776
3236
|
);
|
|
2777
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2778
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2779
|
-
throw new Error("Belief not found.");
|
|
2780
|
-
}
|
|
3237
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2781
3238
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2782
3239
|
const now = Date.now();
|
|
2783
3240
|
const contractId = generateGlobalId();
|
|
@@ -2832,10 +3289,10 @@ var evaluateContract = mutation({
|
|
|
2832
3289
|
if (contract.status === "archived") {
|
|
2833
3290
|
throw new Error("Archived contracts cannot be evaluated.");
|
|
2834
3291
|
}
|
|
2835
|
-
const belief =
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
3292
|
+
const belief = assertBeliefNode(
|
|
3293
|
+
await ctx.db.get(contract.beliefNodeId),
|
|
3294
|
+
"Belief not found for contract."
|
|
3295
|
+
);
|
|
2839
3296
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2840
3297
|
const evaluation = await executeContractEvaluation({
|
|
2841
3298
|
ctx,
|
|
@@ -2873,14 +3330,11 @@ var evaluateEngineeringContracts = mutation({
|
|
|
2873
3330
|
ctx,
|
|
2874
3331
|
args.authenticatedUserId
|
|
2875
3332
|
);
|
|
2876
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2877
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2878
|
-
throw new Error("Belief not found.");
|
|
2879
|
-
}
|
|
3333
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2880
3334
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2881
3335
|
const trigger = args.trigger ?? "event_driven";
|
|
2882
3336
|
const allowedSchedules = resolveSchedulesForTrigger2(
|
|
2883
|
-
trigger
|
|
3337
|
+
normalizeEngineeringTrigger(trigger)
|
|
2884
3338
|
);
|
|
2885
3339
|
const payloadByEvaluator = /* @__PURE__ */ new Map([
|
|
2886
3340
|
["test_runner", args.testOutput],
|
|
@@ -2959,10 +3413,7 @@ var evaluateContractsForTrigger = mutation({
|
|
|
2959
3413
|
ctx,
|
|
2960
3414
|
args.authenticatedUserId
|
|
2961
3415
|
);
|
|
2962
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2963
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2964
|
-
throw new Error("Belief not found.");
|
|
2965
|
-
}
|
|
3416
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2966
3417
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2967
3418
|
return await evaluateContractsForTriggerBatch({
|
|
2968
3419
|
ctx,
|
|
@@ -2985,10 +3436,7 @@ var processContractEvaluationOverflow = internalMutation({
|
|
|
2985
3436
|
},
|
|
2986
3437
|
returns: permissiveReturn,
|
|
2987
3438
|
handler: async (ctx, args) => {
|
|
2988
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2989
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2990
|
-
throw new Error("Belief not found.");
|
|
2991
|
-
}
|
|
3439
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2992
3440
|
return await evaluateContractsForTriggerBatch({
|
|
2993
3441
|
ctx,
|
|
2994
3442
|
belief,
|
|
@@ -3027,15 +3475,9 @@ var getContractStatus = query({
|
|
|
3027
3475
|
const contract = await getContractByContractId(ctx, args.contractId);
|
|
3028
3476
|
contracts = contract ? [contract] : [];
|
|
3029
3477
|
} else if (args.beliefNodeId) {
|
|
3030
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
3031
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
3032
|
-
throw new Error("Belief not found.");
|
|
3033
|
-
}
|
|
3478
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
3034
3479
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
3035
|
-
contracts = await ctx.
|
|
3036
|
-
"by_belief",
|
|
3037
|
-
(q) => q.eq("beliefNodeId", args.beliefNodeId)
|
|
3038
|
-
).collect();
|
|
3480
|
+
contracts = await contractTables(ctx).query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
|
|
3039
3481
|
}
|
|
3040
3482
|
if (contracts.length > 0) {
|
|
3041
3483
|
const contractBeliefDocs = await Promise.all(
|
|
@@ -3043,15 +3485,14 @@ var getContractStatus = query({
|
|
|
3043
3485
|
);
|
|
3044
3486
|
const contractBeliefs = [];
|
|
3045
3487
|
for (const belief of contractBeliefDocs) {
|
|
3046
|
-
|
|
3047
|
-
throw new Error("Belief not found.");
|
|
3048
|
-
}
|
|
3049
|
-
contractBeliefs.push(belief);
|
|
3488
|
+
contractBeliefs.push(assertBeliefNode(belief));
|
|
3050
3489
|
}
|
|
3051
3490
|
await requireTopicReadAccess(ctx, contractBeliefs, userId);
|
|
3052
3491
|
}
|
|
3053
3492
|
if (args.status) {
|
|
3054
|
-
contracts = contracts.filter(
|
|
3493
|
+
contracts = contracts.filter(
|
|
3494
|
+
(contract) => contract.status === args.status
|
|
3495
|
+
);
|
|
3055
3496
|
}
|
|
3056
3497
|
const rows = await Promise.all(
|
|
3057
3498
|
contracts.map(async (contract) => ({
|
|
@@ -3070,21 +3511,22 @@ var getContractCoverage = query({
|
|
|
3070
3511
|
},
|
|
3071
3512
|
returns: permissiveReturn,
|
|
3072
3513
|
handler: async (ctx, args) => {
|
|
3073
|
-
const contracts = await ctx.
|
|
3514
|
+
const contracts = await contractTables(ctx).query("epistemicContracts").withIndex("by_topic", (q) => q.eq("topicId", args.topicId)).collect();
|
|
3074
3515
|
const userId = await resolveAuthenticatedUserId(
|
|
3075
3516
|
ctx,
|
|
3076
3517
|
args.authenticatedUserId
|
|
3077
3518
|
);
|
|
3078
|
-
const
|
|
3519
|
+
const beliefRows = await ctx.db.query("epistemicNodes").withIndex(
|
|
3079
3520
|
"by_topic_type",
|
|
3080
3521
|
(q) => q.eq("topicId", args.topicId).eq("nodeType", "belief")
|
|
3081
3522
|
).collect();
|
|
3523
|
+
const beliefs = beliefRows.map((belief) => assertBeliefNode(belief));
|
|
3082
3524
|
await requireTopicReadAccess(ctx, beliefs, userId);
|
|
3083
3525
|
const recentEvaluationLimit = Math.max(
|
|
3084
3526
|
0,
|
|
3085
3527
|
Math.min(args.recentEvaluationLimit ?? 5, 25)
|
|
3086
3528
|
);
|
|
3087
|
-
const recentEvaluations = recentEvaluationLimit === 0 ? [] : await ctx.
|
|
3529
|
+
const recentEvaluations = recentEvaluationLimit === 0 ? [] : await contractTables(ctx).query("contractEvaluations").withIndex("by_topic_time", (q) => q.eq("topicId", args.topicId)).order("desc").take(recentEvaluationLimit);
|
|
3088
3530
|
const contractBeliefIds = new Set(
|
|
3089
3531
|
contracts.filter((contract) => contract.status !== "archived").map((contract) => String(contract.beliefNodeId))
|
|
3090
3532
|
);
|
|
@@ -3107,6 +3549,23 @@ function inheritContractsForFork(contracts, args) {
|
|
|
3107
3549
|
return contracts.filter((contract) => contract.status !== "archived").map((contract) => createInheritedContractRecord(contract, args));
|
|
3108
3550
|
}
|
|
3109
3551
|
|
|
3110
|
-
|
|
3552
|
+
// src/epistemicContracts.ts
|
|
3553
|
+
var clearEpistemicEvaluators2 = clearEpistemicEvaluators;
|
|
3554
|
+
var getRegisteredEpistemicEvaluators2 = getRegisteredEpistemicEvaluators;
|
|
3555
|
+
var registerEpistemicEvaluator2 = registerEpistemicEvaluator;
|
|
3556
|
+
var createEpistemicContract2 = createEpistemicContract;
|
|
3557
|
+
var evaluateContract2 = evaluateContract;
|
|
3558
|
+
var evaluateContractsForTrigger2 = evaluateContractsForTrigger;
|
|
3559
|
+
var evaluateContradictionStatus2 = evaluateContradictionStatus;
|
|
3560
|
+
var evaluateDependentBeliefCount2 = evaluateDependentBeliefCount;
|
|
3561
|
+
var evaluateEdgeFreshness2 = evaluateEdgeFreshness;
|
|
3562
|
+
var evaluateEngineeringContracts2 = evaluateEngineeringContracts;
|
|
3563
|
+
var evaluateEvidenceCount2 = evaluateEvidenceCount;
|
|
3564
|
+
var getContractCoverage2 = getContractCoverage;
|
|
3565
|
+
var getContractStatus2 = getContractStatus;
|
|
3566
|
+
var inheritContractsForFork2 = inheritContractsForFork;
|
|
3567
|
+
var processContractEvaluationOverflow2 = processContractEvaluationOverflow;
|
|
3568
|
+
|
|
3569
|
+
export { clearEpistemicEvaluators2 as clearEpistemicEvaluators, createEpistemicContract2 as createEpistemicContract, evaluateContract2 as evaluateContract, evaluateContractsForTrigger2 as evaluateContractsForTrigger, evaluateContradictionStatus2 as evaluateContradictionStatus, evaluateDependentBeliefCount2 as evaluateDependentBeliefCount, evaluateEdgeFreshness2 as evaluateEdgeFreshness, evaluateEngineeringContracts2 as evaluateEngineeringContracts, evaluateEvidenceCount2 as evaluateEvidenceCount, getContractCoverage2 as getContractCoverage, getContractStatus2 as getContractStatus, getRegisteredEpistemicEvaluators2 as getRegisteredEpistemicEvaluators, inheritContractsForFork2 as inheritContractsForFork, processContractEvaluationOverflow2 as processContractEvaluationOverflow, registerEpistemicEvaluator2 as registerEpistemicEvaluator };
|
|
3111
3570
|
//# sourceMappingURL=epistemicContracts.js.map
|
|
3112
3571
|
//# sourceMappingURL=epistemicContracts.js.map
|