@lucern/graph-primitives 1.0.29 → 1.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{beliefDecay-DZ6tkLYq.d.ts → beliefDecay-BmkEk5OJ.d.ts} +3 -3
- package/dist/beliefDecay.d.ts +1 -1
- package/dist/beliefDecay.js +448 -314
- package/dist/beliefDecay.js.map +1 -1
- package/dist/{beliefEvidenceLinks-CWOXxxJg.d.ts → beliefEvidenceLinks-BzfjON_6.d.ts} +13 -13
- package/dist/beliefEvidenceLinks.d.ts +1 -1
- package/dist/beliefEvidenceLinks.js +843 -624
- package/dist/beliefEvidenceLinks.js.map +1 -1
- package/dist/beliefEvidenceLinks.operational.d.ts +7 -5
- package/dist/beliefEvidenceLinks.operational.js +91 -18
- package/dist/beliefEvidenceLinks.operational.js.map +1 -1
- package/dist/beliefLifecycle.js.map +1 -1
- package/dist/confidencePropagationDispatch.d.ts +28 -27
- package/dist/confidencePropagationDispatch.js +157 -99
- package/dist/confidencePropagationDispatch.js.map +1 -1
- package/dist/{contradictions-51VLsESq.d.ts → contradictions-BATPuZTL.d.ts} +10 -10
- package/dist/contradictions.d.ts +1 -1
- package/dist/contradictions.js +395 -225
- package/dist/contradictions.js.map +1 -1
- package/dist/convex.d.ts +65 -30
- package/dist/convex.js +7 -3
- package/dist/convex.js.map +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/edgeValidation.js +293 -85
- package/dist/edgeValidation.js.map +1 -1
- package/dist/edges/contains.d.ts +1 -1
- package/dist/edges/contains.js.map +1 -1
- package/dist/edges/contradicts.d.ts +1 -1
- package/dist/edges/contradicts.js.map +1 -1
- package/dist/edges/{dependsOn.d.ts → depends-on.d.ts} +1 -1
- package/dist/edges/{dependsOn.js → depends-on.js} +4 -4
- package/dist/edges/depends-on.js.map +1 -0
- package/dist/edges/{derivedFrom.d.ts → derived-from.d.ts} +1 -1
- package/dist/edges/{derivedFrom.js → derived-from.js} +3 -3
- package/dist/edges/derived-from.js.map +1 -0
- package/dist/edges/elaborates.d.ts +1 -1
- package/dist/edges/elaborates.js.map +1 -1
- package/dist/edges/index.d.ts +7 -3
- package/dist/edges/index.js +7 -4
- package/dist/edges/index.js.map +1 -1
- package/dist/edges/informs.d.ts +1 -1
- package/dist/edges/informs.js.map +1 -1
- package/dist/edges/{propagationTypes.d.ts → propagation-types.d.ts} +14 -14
- package/dist/edges/{propagationTypes.js → propagation-types.js} +3 -3
- package/dist/edges/propagation-types.js.map +1 -0
- package/dist/edges/refutes.d.ts +1 -1
- package/dist/edges/refutes.js.map +1 -1
- package/dist/edges/supports.d.ts +1 -1
- package/dist/edges/supports.js.map +1 -1
- package/dist/edges/tests.d.ts +1 -1
- package/dist/edges/tests.js.map +1 -1
- package/dist/edges/utils.d.ts +1 -1
- package/dist/edges/utils.js.map +1 -1
- package/dist/embeddingTrigger.d.ts +14 -6
- package/dist/embeddingTrigger.js +11 -14
- package/dist/embeddingTrigger.js.map +1 -1
- package/dist/{entityBridge-DMaKooYn.d.ts → entityBridge-BhVDM3pc.d.ts} +5 -5
- package/dist/entityBridge.d.ts +1 -1
- package/dist/entityBridge.js +602 -225
- package/dist/entityBridge.js.map +1 -1
- package/dist/entityCanonicalMatch.d.ts +14 -12
- package/dist/entityCanonicalMatch.js.map +1 -1
- package/dist/{entityLifecycle-CvgSK5FV.d.ts → entityLifecycle-BsfCz9pS.d.ts} +5 -9
- package/dist/entityLifecycle.d.ts +1 -1
- package/dist/entityLifecycle.js +854 -480
- package/dist/entityLifecycle.js.map +1 -1
- package/dist/{entityValidation-KLZ_Xl2D.d.ts → entityValidation-B1yNEHJx.d.ts} +7 -6
- package/dist/entityValidation.d.ts +3 -1
- package/dist/entityValidation.js +60 -8
- package/dist/entityValidation.js.map +1 -1
- package/dist/{epistemicAnswers-C5ib4z6_.d.ts → epistemicAnswers-f47YMu9U.d.ts} +6 -6
- package/dist/epistemicAnswers.d.ts +1 -1
- package/dist/epistemicAnswers.js +587 -545
- package/dist/epistemicAnswers.js.map +1 -1
- package/dist/epistemicBeliefs.admin.d.ts +8 -8
- package/dist/epistemicBeliefs.admin.js +365 -166
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.d.ts +8 -8
- package/dist/epistemicBeliefs.backfills.js +655 -289
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +19 -15
- package/dist/epistemicBeliefs.confidence.js +633 -386
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.d.ts +6 -6
- package/dist/epistemicBeliefs.core.js +717 -371
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +11 -9
- package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
- package/dist/epistemicBeliefs.forkEvidence.js +8 -8
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
- package/dist/epistemicBeliefs.helpers.d.ts +68 -49
- package/dist/epistemicBeliefs.helpers.js +358 -211
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.d.ts +5 -5
- package/dist/epistemicBeliefs.internal.js +1248 -1026
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +4942 -3590
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
- package/dist/epistemicBeliefs.lifecycle.js +1138 -781
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.d.ts +7 -7
- package/dist/epistemicBeliefs.links.js +404 -267
- package/dist/epistemicBeliefs.links.js.map +1 -1
- package/dist/epistemicBeliefs.queries.d.ts +4 -4
- package/dist/epistemicBeliefs.queries.js +175 -20
- package/dist/epistemicBeliefs.queries.js.map +1 -1
- package/dist/epistemicBeliefs.topicAnchor.d.ts +6 -4
- package/dist/epistemicBeliefs.topicAnchor.js +12 -5
- package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
- package/dist/epistemicContracts.d.ts +28 -3
- package/dist/epistemicContracts.evaluators.d.ts +2 -0
- package/dist/epistemicContracts.evaluators.js +1062 -576
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.d.ts +15 -32
- package/dist/epistemicContracts.handlers.js +1829 -1351
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +1131 -636
- package/dist/epistemicContracts.js.map +1 -1
- package/dist/epistemicContracts.metrics.d.ts +2 -0
- package/dist/epistemicContracts.metrics.js +375 -158
- package/dist/epistemicContracts.metrics.js.map +1 -1
- package/dist/epistemicContracts.types.d.ts +87 -81
- package/dist/epistemicEdgeCreation.d.ts +2 -0
- package/dist/epistemicEdgeCreation.js +87 -16
- package/dist/epistemicEdgeCreation.js.map +1 -1
- package/dist/{epistemicEdges-BF-cn4i3.d.ts → epistemicEdges-BGBh0QSP.d.ts} +4 -7
- package/dist/epistemicEdges.d.ts +6 -5
- package/dist/epistemicEdges.handlers.d.ts +3 -3
- package/dist/epistemicEdges.handlers.js +129 -24
- package/dist/epistemicEdges.handlers.js.map +1 -1
- package/dist/epistemicEdges.helpers.d.ts +6 -4
- package/dist/epistemicEdges.helpers.js +37 -2
- package/dist/epistemicEdges.helpers.js.map +1 -1
- package/dist/epistemicEdges.js +1966 -1202
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/epistemicEdges.mutations.d.ts +7 -7
- package/dist/epistemicEdges.mutations.js +956 -579
- package/dist/epistemicEdges.mutations.js.map +1 -1
- package/dist/epistemicEdges.queries.d.ts +16 -16
- package/dist/epistemicEdges.queries.js +639 -367
- package/dist/epistemicEdges.queries.js.map +1 -1
- package/dist/epistemicEdges.types.d.ts +10 -8
- package/dist/epistemicEvidence.d.ts +4 -1
- package/dist/epistemicEvidence.js +933 -532
- package/dist/epistemicEvidence.js.map +1 -1
- package/dist/epistemicEvidenceHelpers.d.ts +26 -10
- package/dist/epistemicEvidenceHelpers.js +239 -200
- package/dist/epistemicEvidenceHelpers.js.map +1 -1
- package/dist/epistemicEvidenceMutations.d.ts +8 -8
- package/dist/epistemicEvidenceMutations.js +840 -692
- package/dist/epistemicEvidenceMutations.js.map +1 -1
- package/dist/epistemicEvidenceQueries.d.ts +8 -8
- package/dist/epistemicEvidenceQueries.js +514 -238
- package/dist/epistemicEvidenceQueries.js.map +1 -1
- package/dist/epistemicHelpers.d.ts +4 -2
- package/dist/epistemicHelpers.js +308 -134
- package/dist/epistemicHelpers.js.map +1 -1
- package/dist/epistemicInsert.d.ts +16 -4
- package/dist/epistemicInsert.js +6 -3
- package/dist/epistemicInsert.js.map +1 -1
- package/dist/epistemicLayerRules.d.ts +10 -8
- package/dist/epistemicLayerRules.js +1 -5
- package/dist/epistemicLayerRules.js.map +1 -1
- package/dist/{epistemicLinking-CfE00tHJ.d.ts → epistemicLinking-CsCDv2cN.d.ts} +3 -3
- package/dist/epistemicLinking.d.ts +1 -1
- package/dist/epistemicLinking.js +177 -100
- package/dist/epistemicLinking.js.map +1 -1
- package/dist/epistemicNodeCreation.d.ts +2 -0
- package/dist/epistemicNodeCreation.js +203 -40
- package/dist/epistemicNodeCreation.js.map +1 -1
- package/dist/{epistemicNodes-BCQxpYx_.d.ts → epistemicNodes-CokAgBHg.d.ts} +3 -3
- package/dist/epistemicNodes.d.ts +3 -3
- package/dist/epistemicNodes.helpers.d.ts +24 -15
- package/dist/epistemicNodes.helpers.js.map +1 -1
- package/dist/epistemicNodes.internal.d.ts +6 -6
- package/dist/epistemicNodes.internal.js +389 -319
- package/dist/epistemicNodes.internal.js.map +1 -1
- package/dist/epistemicNodes.js +700 -504
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.d.ts +6 -6
- package/dist/epistemicNodes.mutations.js +560 -463
- package/dist/epistemicNodes.mutations.js.map +1 -1
- package/dist/epistemicNodes.queries.d.ts +8 -8
- package/dist/epistemicNodes.queries.js +311 -314
- package/dist/epistemicNodes.queries.js.map +1 -1
- package/dist/epistemicNodes.validators.d.ts +2 -2
- package/dist/epistemicNodes.validators.js.map +1 -1
- package/dist/epistemicQuestions.conviction.d.ts +8 -8
- package/dist/epistemicQuestions.conviction.js +665 -484
- package/dist/epistemicQuestions.conviction.js.map +1 -1
- package/dist/epistemicQuestions.create.d.ts +4 -4
- package/dist/epistemicQuestions.create.js +640 -612
- package/dist/epistemicQuestions.create.js.map +1 -1
- package/dist/epistemicQuestions.d.ts +8 -5
- package/dist/epistemicQuestions.evidence.d.ts +2 -2
- package/dist/epistemicQuestions.evidence.js +475 -383
- package/dist/epistemicQuestions.evidence.js.map +1 -1
- package/dist/epistemicQuestions.helpers.d.ts +125 -24
- package/dist/epistemicQuestions.helpers.js +240 -209
- package/dist/epistemicQuestions.helpers.js.map +1 -1
- package/dist/epistemicQuestions.js +3474 -2823
- package/dist/epistemicQuestions.js.map +1 -1
- package/dist/epistemicQuestions.lifecycle.d.ts +2 -2
- package/dist/epistemicQuestions.lifecycle.js +607 -546
- package/dist/epistemicQuestions.lifecycle.js.map +1 -1
- package/dist/epistemicQuestions.queries.d.ts +12 -7
- package/dist/epistemicQuestions.queries.js +305 -244
- package/dist/epistemicQuestions.queries.js.map +1 -1
- package/dist/epistemicQuestions.sprint.d.ts +2 -2
- package/dist/epistemicQuestions.sprint.js +600 -394
- package/dist/epistemicQuestions.sprint.js.map +1 -1
- package/dist/epistemicQuestions.tail.d.ts +6 -6
- package/dist/epistemicQuestions.tail.js +572 -433
- package/dist/epistemicQuestions.tail.js.map +1 -1
- package/dist/{epistemicSources-dlKj58Jp.d.ts → epistemicSources-DQtaEkWs.d.ts} +4 -4
- package/dist/epistemicSources.d.ts +1 -1
- package/dist/epistemicSources.js +351 -311
- package/dist/epistemicSources.js.map +1 -1
- package/dist/evaluators/index.d.ts +8 -6
- package/dist/evaluators/index.js +399 -167
- package/dist/evaluators/index.js.map +1 -1
- package/dist/evaluators/lint-checker-evaluator.d.ts +16 -0
- package/dist/evaluators/{lintCheckerEvaluator.js → lint-checker-evaluator.js} +10 -5
- package/dist/evaluators/lint-checker-evaluator.js.map +1 -0
- package/dist/evaluators/{sentryCheckerEvaluator.d.ts → sentry-checker-evaluator.d.ts} +7 -2
- package/dist/evaluators/{sentryCheckerEvaluator.js → sentry-checker-evaluator.js} +3 -3
- package/dist/evaluators/sentry-checker-evaluator.js.map +1 -0
- package/dist/evaluators/shared.d.ts +2 -2
- package/dist/evaluators/shared.js +3 -1
- package/dist/evaluators/shared.js.map +1 -1
- package/dist/evaluators/{testRunnerEvaluator.d.ts → test-runner-evaluator.d.ts} +6 -1
- package/dist/evaluators/{testRunnerEvaluator.js → test-runner-evaluator.js} +6 -4
- package/dist/evaluators/test-runner-evaluator.js.map +1 -0
- package/dist/evaluators/tsc-checker-evaluator.d.ts +16 -0
- package/dist/evaluators/{tscCheckerEvaluator.js → tsc-checker-evaluator.js} +10 -5
- package/dist/evaluators/tsc-checker-evaluator.js.map +1 -0
- package/dist/graphTypes.js +6 -2
- package/dist/graphTypes.js.map +1 -1
- package/dist/helpers.d.ts +2 -0
- package/dist/helpers.js +313 -93
- package/dist/helpers.js.map +1 -1
- package/dist/{index-C-Kyd7hD.d.ts → index-DZxyC9Pb.d.ts} +7 -6
- package/dist/index.d.ts +86 -83
- package/dist/index.js +16914 -11760
- package/dist/index.js.map +1 -1
- package/dist/invariantEnforcement.d.ts +3 -3
- package/dist/invariantEnforcement.js.map +1 -1
- package/dist/logicalRoleInference.d.ts +2 -0
- package/dist/logicalRoleInference.js +1 -1
- package/dist/logicalRoleInference.js.map +1 -1
- package/dist/matcherFeedbackUtils.d.ts +2 -2
- package/dist/matcherFeedbackUtils.js.map +1 -1
- package/dist/{ontology-matching-C6rrz2VP.d.ts → ontology-matching-C-mYFrir.d.ts} +16 -16
- package/dist/ontology-matching.d.ts +1 -1
- package/dist/{ontologyApproval-CFYmqKmk.d.ts → ontologyApproval-BVt0feJi.d.ts} +10 -10
- package/dist/ontologyApproval.d.ts +1 -1
- package/dist/ontologyApproval.js +7 -1
- package/dist/ontologyApproval.js.map +1 -1
- package/dist/ontologyDefinitions.d.ts +14 -24
- package/dist/ontologyDefinitions.js +269 -34
- package/dist/ontologyDefinitions.js.map +1 -1
- package/dist/ontologyHelpers.d.ts +13 -13
- package/dist/ontologyHelpers.js.map +1 -1
- package/dist/{ontologyRegistry-B67rPJ16.d.ts → ontologyRegistry-CljS-ENv.d.ts} +2 -2
- package/dist/ontologyRegistry.d.ts +1 -1
- package/dist/ontologyRegistry.js +34 -6
- package/dist/ontologyRegistry.js.map +1 -1
- package/dist/{projectionReconciliation-jww2fBI0.d.ts → projectionReconciliation-DnrSgHSQ.d.ts} +4 -4
- package/dist/projectionReconciliation.d.ts +1 -1
- package/dist/projectionReconciliation.js +57 -10
- package/dist/projectionReconciliation.js.map +1 -1
- package/dist/{projectionStaleness-CmdbpjVK.d.ts → projectionStaleness-C8ImQ2zP.d.ts} +17 -17
- package/dist/projectionStaleness.d.ts +1 -1
- package/dist/projectionStaleness.js +8 -2
- package/dist/projectionStaleness.js.map +1 -1
- package/dist/proof-attestation.json +1 -1
- package/dist/{questionEvidenceLinks-DFlyPpAj.d.ts → questionEvidenceLinks-_nPRa-LY.d.ts} +10 -10
- package/dist/questionEvidenceLinks.d.ts +1 -1
- package/dist/questionEvidenceLinks.js +564 -347
- package/dist/questionEvidenceLinks.js.map +1 -1
- package/dist/{resolverTypes-CC8Ea2E2.d.ts → resolverTypes-BOXPxLET.d.ts} +8 -7
- package/dist/resolverTypes.d.ts +4 -2
- package/dist/{resolvers-Br1a6eLV.d.ts → resolvers-B1TIBmRO.d.ts} +3 -1
- package/dist/resolvers.d.ts +5 -3
- package/dist/resolvers.js +121 -77
- package/dist/resolvers.js.map +1 -1
- package/dist/scopeResolverCompat.d.ts +10 -7
- package/dist/scopeResolverCompat.js +106 -123
- package/dist/scopeResolverCompat.js.map +1 -1
- package/dist/{text-matching-DNg4M5Wd.d.ts → text-matching-DzFooju6.d.ts} +7 -7
- package/dist/text-matching.d.ts +1 -1
- package/dist/topicOntologyResolver.d.ts +22 -21
- package/dist/topicOntologyResolver.js +54 -32
- package/dist/topicOntologyResolver.js.map +1 -1
- package/dist/topicProjectOverlay.d.ts +30 -20
- package/dist/topicProjectOverlay.js +120 -76
- package/dist/topicProjectOverlay.js.map +1 -1
- package/dist/{topicScope-7zhyeGl7.d.ts → topicScope-DJVa0mLa.d.ts} +22 -7
- package/dist/topicScope.d.ts +3 -1
- package/dist/topicScope.js +104 -119
- package/dist/topicScope.js.map +1 -1
- package/dist/workflowBridge.d.ts +26 -15
- package/dist/workflowBridge.js +140 -144
- package/dist/workflowBridge.js.map +1 -1
- package/dist/workspaceIsolation.d.ts +14 -12
- package/dist/workspaceIsolation.js +108 -122
- package/dist/workspaceIsolation.js.map +1 -1
- package/package.json +4 -4
- package/dist/edges/dependsOn.js.map +0 -1
- package/dist/edges/derivedFrom.js.map +0 -1
- package/dist/edges/propagationTypes.js.map +0 -1
- package/dist/evaluators/lintCheckerEvaluator.d.ts +0 -11
- package/dist/evaluators/lintCheckerEvaluator.js.map +0 -1
- package/dist/evaluators/sentryCheckerEvaluator.js.map +0 -1
- package/dist/evaluators/testRunnerEvaluator.js.map +0 -1
- package/dist/evaluators/tscCheckerEvaluator.d.ts +0 -11
- package/dist/evaluators/tscCheckerEvaluator.js.map +0 -1
- package/dist/{epistemicQuestions-bwHd2FWE.d.ts → epistemicQuestions-Do1fhYm5.d.ts} +4 -4
|
@@ -1,15 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { normalizeTupleContradictionPolicy, mkOpinion, conditionalDeduction, project, dampedDependencyCascade, hasProjectedOpinionChanged, confidenceFromSL, detectTupleContradiction, evaluateTupleContradictionTransition, deriveContractModulationPlan, deriveContractStatus, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, readOpinionFromRecord, parseEvidentialEvaluatorConfig, compareMetricValue, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, resolveComparisonResult, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig, createInheritedContractRecord } from '@lucern/confidence';
|
|
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';
|
|
8
|
-
import {
|
|
9
|
+
import { checkProjectAccess, requireScopeWriteAccess } from '@lucern/access-control/access';
|
|
9
10
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
10
11
|
import { generateGlobalId } from '@lucern/contracts/ids';
|
|
11
12
|
|
|
12
|
-
// 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
|
+
}
|
|
13
35
|
|
|
14
36
|
// src/beliefLifecycle.ts
|
|
15
37
|
var BELIEF_STATUS_VALUES = [
|
|
@@ -131,24 +153,6 @@ function promoteBeliefStatusAfterScoring(status, opts) {
|
|
|
131
153
|
}
|
|
132
154
|
return status;
|
|
133
155
|
}
|
|
134
|
-
var api = anyApi;
|
|
135
|
-
componentsGeneric();
|
|
136
|
-
var internal = anyApi;
|
|
137
|
-
var internalMutation = internalMutationGeneric;
|
|
138
|
-
var mutation = mutationGeneric;
|
|
139
|
-
var query = queryGeneric;
|
|
140
|
-
|
|
141
|
-
// src/debug.ts
|
|
142
|
-
function isGraphPrimitiveDebugEnabled() {
|
|
143
|
-
const env = globalThis.process?.env;
|
|
144
|
-
return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
|
|
145
|
-
}
|
|
146
|
-
function debugGraphPrimitiveFallback(message, context) {
|
|
147
|
-
if (!isGraphPrimitiveDebugEnabled()) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
console.debug(message, context ?? {});
|
|
151
|
-
}
|
|
152
156
|
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
153
157
|
async function resolveTopicNodeScopeOrNull(ctx, ref) {
|
|
154
158
|
if (!ctx?.db || typeof ctx.db.query !== "function") {
|
|
@@ -183,13 +187,15 @@ function asMappedProjectId(topic) {
|
|
|
183
187
|
if (!topic) {
|
|
184
188
|
return;
|
|
185
189
|
}
|
|
186
|
-
const directLegacyProjectId = normalizeScopeValue(
|
|
190
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
191
|
+
topic[LEGACY_SCOPE_FIELD]
|
|
192
|
+
);
|
|
187
193
|
if (directLegacyProjectId) {
|
|
188
194
|
return directLegacyProjectId;
|
|
189
195
|
}
|
|
190
196
|
const metadata = topic.metadata || {};
|
|
191
197
|
const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
192
|
-
return candidate ? candidate : void 0;
|
|
198
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
193
199
|
}
|
|
194
200
|
function normalizeScopeValue(value) {
|
|
195
201
|
if (typeof value !== "string") {
|
|
@@ -214,8 +220,9 @@ function pickPrimaryTopic(candidates) {
|
|
|
214
220
|
})[0];
|
|
215
221
|
}
|
|
216
222
|
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
223
|
+
const query2 = ctx.db.query("topics");
|
|
217
224
|
try {
|
|
218
|
-
return await
|
|
225
|
+
return await query2.withIndex(
|
|
219
226
|
"by_graph_scope_project",
|
|
220
227
|
(q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
|
|
221
228
|
).collect();
|
|
@@ -227,7 +234,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
|
227
234
|
scopeId
|
|
228
235
|
}
|
|
229
236
|
);
|
|
230
|
-
const topics = await
|
|
237
|
+
const topics = await query2.collect();
|
|
231
238
|
return topics.filter((topic) => {
|
|
232
239
|
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
233
240
|
const mappedProjectId = asMappedProjectId(topic);
|
|
@@ -283,137 +290,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
|
283
290
|
let current = topic;
|
|
284
291
|
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
285
292
|
current = await ctx.db.get(current.parentTopicId);
|
|
286
|
-
if (!current)
|
|
293
|
+
if (!current) {
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
287
296
|
if (!tenantId) {
|
|
288
297
|
tenantId = normalizeScopeValue(current.tenantId);
|
|
289
298
|
}
|
|
290
299
|
if (!workspaceId) {
|
|
291
300
|
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
292
301
|
}
|
|
293
|
-
if (tenantId && workspaceId)
|
|
302
|
+
if (tenantId && workspaceId) {
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
294
305
|
}
|
|
295
306
|
return { tenantId, workspaceId };
|
|
296
307
|
}
|
|
297
308
|
async function resolveTopicProjectScope(ctx, args) {
|
|
298
309
|
if (args.topicId) {
|
|
299
|
-
|
|
300
|
-
try {
|
|
301
|
-
topic = await ctx.db.get(
|
|
302
|
-
args.topicId
|
|
303
|
-
);
|
|
304
|
-
} catch (error) {
|
|
305
|
-
debugGraphPrimitiveFallback(
|
|
306
|
-
"[topicScope] Failed to load topic by direct id",
|
|
307
|
-
{
|
|
308
|
-
error,
|
|
309
|
-
topicId: args.topicId
|
|
310
|
-
}
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
if (!topic) {
|
|
314
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
315
|
-
}
|
|
316
|
-
if (!topic) {
|
|
317
|
-
topic = pickPrimaryTopic(
|
|
318
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
319
|
-
) ?? null;
|
|
320
|
-
}
|
|
321
|
-
if (!topic) {
|
|
322
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
323
|
-
ctx,
|
|
324
|
-
String(args.topicId)
|
|
325
|
-
);
|
|
326
|
-
if (nodeScope) {
|
|
327
|
-
return nodeScope;
|
|
328
|
-
}
|
|
329
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
330
|
-
}
|
|
331
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
332
|
-
const mapped = asMappedProjectId(topic);
|
|
333
|
-
if (mapped) {
|
|
334
|
-
return {
|
|
335
|
-
topicId: topic._id,
|
|
336
|
-
projectId: mapped,
|
|
337
|
-
tenantId: inherited.tenantId,
|
|
338
|
-
workspaceId: inherited.workspaceId,
|
|
339
|
-
source: "topic"
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
return {
|
|
343
|
-
topicId: topic._id,
|
|
344
|
-
tenantId: inherited.tenantId,
|
|
345
|
-
workspaceId: inherited.workspaceId,
|
|
346
|
-
source: "topic"
|
|
347
|
-
};
|
|
310
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
348
311
|
}
|
|
349
312
|
if (args.projectId) {
|
|
350
|
-
|
|
351
|
-
try {
|
|
352
|
-
directTopic = await ctx.db.get(
|
|
353
|
-
args.projectId
|
|
354
|
-
);
|
|
355
|
-
} catch (error) {
|
|
356
|
-
debugGraphPrimitiveFallback(
|
|
357
|
-
"[topicScope] Failed to load direct project topic",
|
|
358
|
-
{
|
|
359
|
-
error,
|
|
360
|
-
projectId: args.projectId
|
|
361
|
-
}
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
if (directTopic) {
|
|
365
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
366
|
-
const mapped = asMappedProjectId(directTopic);
|
|
367
|
-
return {
|
|
368
|
-
topicId: directTopic._id,
|
|
369
|
-
projectId: mapped ?? args.projectId,
|
|
370
|
-
tenantId: inherited.tenantId,
|
|
371
|
-
workspaceId: inherited.workspaceId,
|
|
372
|
-
source: "topic_inferred"
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
376
|
-
if (directTopic) {
|
|
377
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
378
|
-
const mapped = asMappedProjectId(directTopic);
|
|
379
|
-
return {
|
|
380
|
-
topicId: directTopic._id,
|
|
381
|
-
projectId: mapped ?? args.projectId,
|
|
382
|
-
tenantId: inherited.tenantId,
|
|
383
|
-
workspaceId: inherited.workspaceId,
|
|
384
|
-
source: "topic_inferred"
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
388
|
-
const primary = pickPrimaryTopic(topics);
|
|
389
|
-
if (primary) {
|
|
390
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
391
|
-
return {
|
|
392
|
-
topicId: primary._id,
|
|
393
|
-
projectId: args.projectId,
|
|
394
|
-
tenantId: inherited.tenantId,
|
|
395
|
-
workspaceId: inherited.workspaceId,
|
|
396
|
-
source: "project_mapped_topic"
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
400
|
-
ctx,
|
|
401
|
-
String(args.projectId)
|
|
402
|
-
);
|
|
403
|
-
if (nodeScope) {
|
|
404
|
-
return {
|
|
405
|
-
...nodeScope,
|
|
406
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
throw new Error(
|
|
410
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
411
|
-
);
|
|
313
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
412
314
|
}
|
|
413
315
|
throw new Error(
|
|
414
316
|
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
415
317
|
);
|
|
416
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
|
+
}
|
|
417
402
|
({
|
|
418
403
|
projectId: v.optional(v.string()),
|
|
419
404
|
topicId: v.optional(v.string())
|
|
@@ -481,9 +466,10 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
|
|
|
481
466
|
if (resolved.tenantId || resolved.workspaceId) {
|
|
482
467
|
return resolved;
|
|
483
468
|
}
|
|
484
|
-
|
|
469
|
+
const topicId = normalizeScopeValue2(node.topicId);
|
|
470
|
+
if (topicId) {
|
|
485
471
|
const topicScope = await resolveTopicProjectScope(ctx, {
|
|
486
|
-
topicId
|
|
472
|
+
topicId
|
|
487
473
|
});
|
|
488
474
|
return {
|
|
489
475
|
...resolved,
|
|
@@ -503,8 +489,6 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
|
|
|
503
489
|
}
|
|
504
490
|
return resolved;
|
|
505
491
|
}
|
|
506
|
-
|
|
507
|
-
// src/epistemicBeliefs.helpers.ts
|
|
508
492
|
v.id("epistemicNodes");
|
|
509
493
|
var DEFAULT_CONFIDENCE_POLICY = {
|
|
510
494
|
scoringMode: "after_worktree",
|
|
@@ -584,7 +568,10 @@ function resolveBeliefStatus(node, metadata) {
|
|
|
584
568
|
});
|
|
585
569
|
}
|
|
586
570
|
async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
|
|
587
|
-
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();
|
|
588
575
|
for (const membership of clusterMembership) {
|
|
589
576
|
const worktree = await ctx.db.get(membership.worktreeId);
|
|
590
577
|
if (worktree?.status === "completed" || worktree?.status === "merged") {
|
|
@@ -595,7 +582,10 @@ async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
|
|
|
595
582
|
}
|
|
596
583
|
async function getActiveConfidencePolicy(ctx) {
|
|
597
584
|
try {
|
|
598
|
-
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();
|
|
599
589
|
return {
|
|
600
590
|
scoringMode: activeConfig?.confidencePolicy === "always" ? "always" : DEFAULT_CONFIDENCE_POLICY.scoringMode,
|
|
601
591
|
tupleContradiction: normalizeTupleContradictionPolicy(
|
|
@@ -748,7 +738,7 @@ var dependsOnPropagationSpec = {
|
|
|
748
738
|
description: "Structural gating. Textbook conditional deduction when edge conditionals exist, otherwise damped dependency cascade through downstream chains."
|
|
749
739
|
};
|
|
750
740
|
|
|
751
|
-
// src/edges/
|
|
741
|
+
// src/edges/derived-from.ts
|
|
752
742
|
var derivedFromPropagationSpec = {
|
|
753
743
|
edgeType: "derived_from",
|
|
754
744
|
direction: "incoming",
|
|
@@ -801,7 +791,7 @@ var informsPropagationSpec = {
|
|
|
801
791
|
description: "Evidence-bearing influence. Informs can chain through the graph with light per-hop damping."
|
|
802
792
|
};
|
|
803
793
|
|
|
804
|
-
// src/edges/
|
|
794
|
+
// src/edges/propagation-types.ts
|
|
805
795
|
function isPropagationTraversalDirection(direction) {
|
|
806
796
|
return direction === "outgoing" || direction === "incoming";
|
|
807
797
|
}
|
|
@@ -874,6 +864,9 @@ var testsPropagationSpec = {
|
|
|
874
864
|
};
|
|
875
865
|
|
|
876
866
|
// src/edges/index.ts
|
|
867
|
+
var canContinueTransitively2 = canContinueTransitively;
|
|
868
|
+
var canTraverseHop2 = canTraverseHop;
|
|
869
|
+
var isPropagationTraversalDirection2 = isPropagationTraversalDirection;
|
|
877
870
|
var EDGE_PROPAGATION_SPECS = [
|
|
878
871
|
supportsPropagationSpec,
|
|
879
872
|
informsPropagationSpec,
|
|
@@ -890,16 +883,15 @@ function getEdgePropagationSpecs() {
|
|
|
890
883
|
return EDGE_PROPAGATION_SPECS;
|
|
891
884
|
}
|
|
892
885
|
function getTraversalDirections(direction) {
|
|
893
|
-
if (
|
|
886
|
+
if (isPropagationTraversalDirection2(direction)) {
|
|
894
887
|
return [direction];
|
|
895
888
|
}
|
|
896
889
|
return ["outgoing", "incoming"];
|
|
897
890
|
}
|
|
898
891
|
|
|
899
892
|
// src/confidencePropagationDispatch.ts
|
|
900
|
-
function
|
|
901
|
-
|
|
902
|
-
return targetNodeId ?? void 0;
|
|
893
|
+
function nodeIdToCacheKey(nodeId) {
|
|
894
|
+
return String(nodeId);
|
|
903
895
|
}
|
|
904
896
|
function readNodeOpinion(node) {
|
|
905
897
|
const metadata = node.metadata ?? {};
|
|
@@ -915,118 +907,354 @@ function readNodeOpinion(node) {
|
|
|
915
907
|
return mkOpinion(0, 0, 1, 0.5);
|
|
916
908
|
}
|
|
917
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
|
+
}
|
|
918
1049
|
async function collectConfidencePropagationDispatches(args) {
|
|
919
1050
|
const dispatchesByTargetId = /* @__PURE__ */ new Map();
|
|
920
1051
|
const opinionCache = /* @__PURE__ */ new Map();
|
|
921
1052
|
const nodeCache = /* @__PURE__ */ new Map();
|
|
922
1053
|
const traversalSpecs = args.traversalSpecs ?? getEdgePropagationSpecs();
|
|
1054
|
+
const scope = {
|
|
1055
|
+
args,
|
|
1056
|
+
dispatchesByTargetId,
|
|
1057
|
+
opinionCache,
|
|
1058
|
+
nodeCache,
|
|
1059
|
+
traversalSpecs
|
|
1060
|
+
};
|
|
923
1061
|
const queue = [
|
|
924
|
-
|
|
925
|
-
nodeId: args.sourceNodeId,
|
|
926
|
-
opinion: args.sourceOpinion,
|
|
927
|
-
hop: 0,
|
|
928
|
-
visitedNodeIds: /* @__PURE__ */ new Set([String(args.sourceNodeId)])
|
|
929
|
-
}
|
|
1062
|
+
buildInitialState(args.sourceNodeId, args.sourceOpinion)
|
|
930
1063
|
];
|
|
931
|
-
const loadNode = async (nodeId) => {
|
|
932
|
-
const cacheKey = String(nodeId);
|
|
933
|
-
if (!nodeCache.has(cacheKey)) {
|
|
934
|
-
nodeCache.set(cacheKey, await args.getNode(nodeId));
|
|
935
|
-
}
|
|
936
|
-
return nodeCache.get(cacheKey) ?? null;
|
|
937
|
-
};
|
|
938
1064
|
while (queue.length > 0) {
|
|
939
1065
|
const state = queue.shift();
|
|
940
1066
|
if (!state) {
|
|
941
1067
|
continue;
|
|
942
1068
|
}
|
|
943
|
-
|
|
944
|
-
const nextHop = state.hop + 1;
|
|
945
|
-
if (!canTraverseHop(spec, nextHop)) {
|
|
946
|
-
continue;
|
|
947
|
-
}
|
|
948
|
-
for (const direction of getTraversalDirections(spec.direction)) {
|
|
949
|
-
const edges = await args.queryEdges({
|
|
950
|
-
nodeId: state.nodeId,
|
|
951
|
-
spec,
|
|
952
|
-
direction,
|
|
953
|
-
hop: nextHop
|
|
954
|
-
});
|
|
955
|
-
for (const edge of edges) {
|
|
956
|
-
if (args.sourceScope && !edgeMatchesWorkspaceReasoningScope(edge, args.sourceScope)) {
|
|
957
|
-
continue;
|
|
958
|
-
}
|
|
959
|
-
const targetNodeId = resolveTraversalTargetNodeId(edge, direction);
|
|
960
|
-
if (!targetNodeId) {
|
|
961
|
-
continue;
|
|
962
|
-
}
|
|
963
|
-
if (state.visitedNodeIds.has(String(targetNodeId))) {
|
|
964
|
-
continue;
|
|
965
|
-
}
|
|
966
|
-
const targetNode = await loadNode(targetNodeId);
|
|
967
|
-
if (!targetNode || targetNode.nodeType !== "belief") {
|
|
968
|
-
continue;
|
|
969
|
-
}
|
|
970
|
-
if (args.sourceScope && !nodeMatchesWorkspaceReasoningScope(targetNode, args.sourceScope)) {
|
|
971
|
-
continue;
|
|
972
|
-
}
|
|
973
|
-
const cacheKey = String(targetNodeId);
|
|
974
|
-
const targetOpinion = opinionCache.get(cacheKey) ?? readNodeOpinion(targetNode);
|
|
975
|
-
const result = spec.operator(state.opinion, targetOpinion, edge, {
|
|
976
|
-
hop: nextHop,
|
|
977
|
-
sourceNodeId: state.nodeId,
|
|
978
|
-
targetNodeId,
|
|
979
|
-
traversedDirection: direction,
|
|
980
|
-
spec
|
|
981
|
-
});
|
|
982
|
-
if (!result || !hasProjectedOpinionChanged(targetOpinion, result.opinion)) {
|
|
983
|
-
continue;
|
|
984
|
-
}
|
|
985
|
-
const projectedOpinion = mkOpinion(
|
|
986
|
-
result.opinion.b,
|
|
987
|
-
result.opinion.d,
|
|
988
|
-
result.opinion.u,
|
|
989
|
-
result.opinion.a
|
|
990
|
-
);
|
|
991
|
-
opinionCache.set(cacheKey, projectedOpinion);
|
|
992
|
-
const existingDispatch = dispatchesByTargetId.get(cacheKey);
|
|
993
|
-
dispatchesByTargetId.set(cacheKey, {
|
|
994
|
-
targetNodeId,
|
|
995
|
-
edgeType: spec.edgeType,
|
|
996
|
-
traversedDirection: direction,
|
|
997
|
-
weight: edge.weight ?? 1,
|
|
998
|
-
opinion: projectedOpinion,
|
|
999
|
-
operator: result.operator,
|
|
1000
|
-
rationale: existingDispatch ? `${existingDispatch.rationale}; ${result.rationale}` : result.rationale,
|
|
1001
|
-
hop: nextHop
|
|
1002
|
-
});
|
|
1003
|
-
if (canContinueTransitively(spec, nextHop)) {
|
|
1004
|
-
queue.push({
|
|
1005
|
-
nodeId: targetNodeId,
|
|
1006
|
-
opinion: projectedOpinion,
|
|
1007
|
-
hop: nextHop,
|
|
1008
|
-
visitedNodeIds: /* @__PURE__ */ new Set([
|
|
1009
|
-
...state.visitedNodeIds,
|
|
1010
|
-
String(targetNodeId)
|
|
1011
|
-
])
|
|
1012
|
-
});
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1069
|
+
await processQueuedState(state, queue, scope);
|
|
1017
1070
|
}
|
|
1018
|
-
return
|
|
1019
|
-
if (left.hop !== right.hop) {
|
|
1020
|
-
return left.hop - right.hop;
|
|
1021
|
-
}
|
|
1022
|
-
return String(left.targetNodeId).localeCompare(String(right.targetNodeId));
|
|
1023
|
-
});
|
|
1071
|
+
return sortDispatches(dispatchesByTargetId.values());
|
|
1024
1072
|
}
|
|
1025
1073
|
|
|
1026
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
|
+
}
|
|
1027
1207
|
async function applyBeliefConfidenceChange(ctx, args) {
|
|
1028
1208
|
const now = Date.now();
|
|
1029
|
-
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));
|
|
1030
1258
|
if (!node) {
|
|
1031
1259
|
throwStructuredMutationError({
|
|
1032
1260
|
message: "Node not found.",
|
|
@@ -1037,59 +1265,28 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1037
1265
|
details: { nodeId: args.nodeId }
|
|
1038
1266
|
});
|
|
1039
1267
|
}
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
invariantCode: "entity.no_confidence",
|
|
1046
|
-
suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. appendSlScoring is for belief nodes only.",
|
|
1047
|
-
details: { nodeId: args.nodeId, nodeType: node.nodeType }
|
|
1048
|
-
});
|
|
1049
|
-
}
|
|
1050
|
-
if (!node.projectId) {
|
|
1051
|
-
throwStructuredMutationError({
|
|
1052
|
-
message: "Belief has no project scope.",
|
|
1053
|
-
status: 400,
|
|
1054
|
-
code: "MISSING_SCOPE",
|
|
1055
|
-
invariantCode: "belief.project_required",
|
|
1056
|
-
suggestion: "Belief must have a projectId before SL scoring can be appended.",
|
|
1057
|
-
details: { nodeId: args.nodeId }
|
|
1058
|
-
});
|
|
1059
|
-
}
|
|
1060
|
-
await requireScopeWriteAccess(
|
|
1061
|
-
ctx,
|
|
1062
|
-
node.projectId,
|
|
1063
|
-
args.authenticatedUserId
|
|
1064
|
-
);
|
|
1065
|
-
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);
|
|
1066
1273
|
const currentBeliefStatus = resolveBeliefStatus(node, existingMetadata);
|
|
1067
1274
|
const confidencePolicy = await getActiveConfidencePolicy(ctx);
|
|
1068
|
-
if (confidencePolicy.scoringMode === "after_worktree" && isPreValidationBeliefStatus(currentBeliefStatus)) {
|
|
1069
|
-
const hasCompletedWorktree = await hasCompletedWorktreeForBelief(
|
|
1070
|
-
ctx,
|
|
1071
|
-
args.nodeId
|
|
1072
|
-
);
|
|
1073
|
-
if (!hasCompletedWorktree) {
|
|
1074
|
-
throwStructuredMutationError({
|
|
1075
|
-
message: "Cannot score belief before worktree completion. Complete a worktree that tests this belief first.",
|
|
1076
|
-
status: 409,
|
|
1077
|
-
code: "CONFLICT",
|
|
1078
|
-
invariantCode: "belief.confidence_append_only",
|
|
1079
|
-
suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
|
|
1080
|
-
details: { nodeId: args.nodeId }
|
|
1081
|
-
});
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
1275
|
const previousConfidence = node.confidence || 0.5;
|
|
1085
1276
|
const predictionMeta = node.predictionMeta || existingMetadata.predictionMeta;
|
|
1086
1277
|
const previousOpinion = readBeliefOpinionSnapshot(node, existingMetadata);
|
|
1087
|
-
const
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
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
|
+
);
|
|
1093
1290
|
const isFirstScoring = typeof node.confidence !== "number" || !Number.isFinite(node.confidence);
|
|
1094
1291
|
const previousTupleContradicted = readTupleContradictedFlag(node.tupleContradicted) ?? readTupleContradictedFlag(existingMetadata.tupleContradicted) ?? detectTupleContradiction(
|
|
1095
1292
|
previousOpinion,
|
|
@@ -1110,79 +1307,121 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1110
1307
|
predictionMeta,
|
|
1111
1308
|
metadata: existingMetadata
|
|
1112
1309
|
});
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
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;
|
|
1131
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) {
|
|
1132
1368
|
await ctx.db.patch(args.nodeId, {
|
|
1133
|
-
confidence: derivedConfidence,
|
|
1134
|
-
beliefStatus: newBeliefStatus,
|
|
1135
|
-
tupleContradicted: tupleTransition.tupleContradicted,
|
|
1136
|
-
updatedAt: now,
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
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,
|
|
1142
1377
|
metadata: {
|
|
1143
|
-
...existingMetadata,
|
|
1144
|
-
beliefStatus: newBeliefStatus,
|
|
1145
|
-
slBelief:
|
|
1146
|
-
slDisbelief:
|
|
1147
|
-
slUncertainty:
|
|
1148
|
-
slBaseRate:
|
|
1149
|
-
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
|
|
1150
1385
|
}
|
|
1151
1386
|
});
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
edgeType: "relates_to_thesis",
|
|
1165
|
-
weight: derivedConfidence,
|
|
1166
|
-
createdBy: args.authenticatedUserId,
|
|
1167
|
-
topicId: String(node.projectId),
|
|
1168
|
-
fromNodeType: "belief",
|
|
1169
|
-
toNodeType: "theme",
|
|
1170
|
-
fromLayer: "L3",
|
|
1171
|
-
toLayer: "L3"
|
|
1172
|
-
});
|
|
1173
|
-
}
|
|
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;
|
|
1174
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
|
+
});
|
|
1175
1413
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1414
|
+
}
|
|
1415
|
+
async function insertBeliefConfidenceRecord(ctx, args, state, tupleContradictionId, now) {
|
|
1416
|
+
return await ctx.db.insert("beliefConfidence", {
|
|
1178
1417
|
...buildBeliefConfidenceRow({
|
|
1179
1418
|
beliefId: args.nodeId,
|
|
1180
|
-
belief:
|
|
1181
|
-
disbelief:
|
|
1182
|
-
uncertainty:
|
|
1183
|
-
baseRate:
|
|
1419
|
+
belief: state.nextOpinion.b,
|
|
1420
|
+
disbelief: state.nextOpinion.d,
|
|
1421
|
+
uncertainty: state.nextOpinion.u,
|
|
1422
|
+
baseRate: state.nextOpinion.a,
|
|
1184
1423
|
trigger: args.trigger,
|
|
1185
|
-
rationale: storedRationale,
|
|
1424
|
+
rationale: state.storedRationale,
|
|
1186
1425
|
assessedBy: args.authenticatedUserId,
|
|
1187
1426
|
assessedAt: now,
|
|
1188
1427
|
slOperator: args.slOperator,
|
|
@@ -1191,25 +1430,23 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1191
1430
|
triggeringWorktreeId: args.triggeringWorktreeId
|
|
1192
1431
|
})
|
|
1193
1432
|
});
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
operation: "upsert"
|
|
1197
|
-
});
|
|
1433
|
+
}
|
|
1434
|
+
async function insertConfidenceAudit(ctx, args, node, state, tupleContradictionId, now) {
|
|
1198
1435
|
await ctx.db.insert("epistemicAudit", {
|
|
1199
1436
|
entityType: "belief",
|
|
1200
1437
|
entityId: args.nodeId,
|
|
1201
1438
|
changeType: "confidence_changed",
|
|
1202
1439
|
previousState: {
|
|
1203
|
-
confidence: previousConfidence,
|
|
1204
|
-
tupleContradicted: previousTupleContradicted
|
|
1440
|
+
confidence: state.previousConfidence,
|
|
1441
|
+
tupleContradicted: state.previousTupleContradicted
|
|
1205
1442
|
},
|
|
1206
1443
|
newState: {
|
|
1207
|
-
opinion: nextOpinion,
|
|
1208
|
-
confidence: derivedConfidence,
|
|
1444
|
+
opinion: state.nextOpinion,
|
|
1445
|
+
confidence: state.derivedConfidence,
|
|
1209
1446
|
trigger: args.trigger,
|
|
1210
|
-
rationale: storedRationale,
|
|
1211
|
-
tupleContradicted: tupleTransition.tupleContradicted,
|
|
1212
|
-
tupleContradictionPolicy: tupleTransition.policy,
|
|
1447
|
+
rationale: state.storedRationale,
|
|
1448
|
+
tupleContradicted: state.tupleTransition.tupleContradicted,
|
|
1449
|
+
tupleContradictionPolicy: state.tupleTransition.policy,
|
|
1213
1450
|
...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
|
|
1214
1451
|
},
|
|
1215
1452
|
changedBy: args.authenticatedUserId,
|
|
@@ -1218,28 +1455,39 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1218
1455
|
projectId: node.projectId,
|
|
1219
1456
|
topicId: node.topicId
|
|
1220
1457
|
});
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
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;
|
|
1241
1486
|
}
|
|
1242
|
-
|
|
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) {
|
|
1243
1491
|
await ctx.scheduler.runAfter(
|
|
1244
1492
|
5e3,
|
|
1245
1493
|
internal.bi.contradictionSemanticDetector.scanAffectedBeliefs,
|
|
@@ -1256,13 +1504,6 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1256
1504
|
{ nodeId: args.nodeId }
|
|
1257
1505
|
);
|
|
1258
1506
|
}
|
|
1259
|
-
return {
|
|
1260
|
-
nodeId: args.nodeId,
|
|
1261
|
-
previousConfidence,
|
|
1262
|
-
newConfidence: derivedConfidence,
|
|
1263
|
-
opinion: { b: slB, d: slD, u: slU, a: slA },
|
|
1264
|
-
beliefConfidenceId
|
|
1265
|
-
};
|
|
1266
1507
|
}
|
|
1267
1508
|
function propagationPressureLabel(edgeType, weight) {
|
|
1268
1509
|
if (edgeType === "contradicts" || edgeType === "refutes") {
|
|
@@ -1290,7 +1531,7 @@ internalMutation({
|
|
|
1290
1531
|
args.opinion_u,
|
|
1291
1532
|
args.opinion_a
|
|
1292
1533
|
);
|
|
1293
|
-
const sourceNode = await ctx.db.get(args.nodeId);
|
|
1534
|
+
const sourceNode = readConfidenceBeliefNode(await ctx.db.get(args.nodeId));
|
|
1294
1535
|
const sourceScope = await resolveNodeScopeForWorkspaceIsolation(
|
|
1295
1536
|
ctx,
|
|
1296
1537
|
sourceNode
|
|
@@ -1299,16 +1540,20 @@ internalMutation({
|
|
|
1299
1540
|
sourceNodeId: args.nodeId,
|
|
1300
1541
|
sourceOpinion,
|
|
1301
1542
|
sourceScope,
|
|
1302
|
-
queryEdges: async ({ nodeId, spec, direction }) =>
|
|
1303
|
-
|
|
1543
|
+
queryEdges: async ({ nodeId, spec, direction }) => readRowList(
|
|
1544
|
+
await ctx.db.query("epistemicEdges").withIndex(
|
|
1304
1545
|
direction === "outgoing" ? "by_from_type" : "by_to_type",
|
|
1305
1546
|
(q) => direction === "outgoing" ? q.eq("fromNodeId", nodeId).eq("edgeType", spec.edgeType) : q.eq("toNodeId", nodeId).eq("edgeType", spec.edgeType)
|
|
1306
|
-
).collect()
|
|
1307
|
-
|
|
1308
|
-
|
|
1547
|
+
).collect(),
|
|
1548
|
+
readPropagationEdge
|
|
1549
|
+
),
|
|
1550
|
+
getNode: async (nodeId) => readConfidenceBeliefNode(await ctx.db.get(nodeId))
|
|
1309
1551
|
});
|
|
1310
1552
|
for (const dispatch of dispatches) {
|
|
1311
|
-
const pressureLabel = propagationPressureLabel(
|
|
1553
|
+
const pressureLabel = propagationPressureLabel(
|
|
1554
|
+
dispatch.edgeType,
|
|
1555
|
+
dispatch.weight
|
|
1556
|
+
);
|
|
1312
1557
|
await applyBeliefConfidenceChange(ctx, {
|
|
1313
1558
|
nodeId: dispatch.targetNodeId,
|
|
1314
1559
|
belief: dispatch.opinion.b,
|
|
@@ -1338,9 +1583,7 @@ var ACTIVE_CONTRADICTION_STATUSES = /* @__PURE__ */ new Set([
|
|
|
1338
1583
|
"investigating",
|
|
1339
1584
|
"accepted_as_permanent"
|
|
1340
1585
|
]);
|
|
1341
|
-
var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
1342
|
-
"depends_on"
|
|
1343
|
-
]);
|
|
1586
|
+
var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set(["depends_on"]);
|
|
1344
1587
|
function classifyContradictionStatus(status) {
|
|
1345
1588
|
if (typeof status !== "string") {
|
|
1346
1589
|
return "active";
|
|
@@ -1353,6 +1596,99 @@ function classifyContradictionStatus(status) {
|
|
|
1353
1596
|
}
|
|
1354
1597
|
return "resolved";
|
|
1355
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
|
+
}
|
|
1356
1692
|
function getEdgeTimestamp(edge) {
|
|
1357
1693
|
if (typeof edge.updatedAt === "number") {
|
|
1358
1694
|
return edge.updatedAt;
|
|
@@ -1365,22 +1701,86 @@ function getEdgeTimestamp(edge) {
|
|
|
1365
1701
|
}
|
|
1366
1702
|
return null;
|
|
1367
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
|
+
}
|
|
1368
1770
|
async function getEvidenceLinks(ctx, beliefNodeId) {
|
|
1369
|
-
const edges = await ctx
|
|
1370
|
-
"by_to_type",
|
|
1371
|
-
(q) => q.eq("toNodeId", beliefNodeId).eq("edgeType", "informs")
|
|
1372
|
-
).collect();
|
|
1771
|
+
const edges = await collectIncomingEdgeRows(ctx, beliefNodeId, "informs");
|
|
1373
1772
|
if (edges.length === 0) {
|
|
1374
1773
|
return [];
|
|
1375
1774
|
}
|
|
1376
|
-
const
|
|
1377
|
-
|
|
1378
|
-
const node =
|
|
1379
|
-
if (
|
|
1380
|
-
|
|
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;
|
|
1381
1780
|
}
|
|
1382
|
-
|
|
1383
|
-
}
|
|
1781
|
+
links.push({ edge, node });
|
|
1782
|
+
}
|
|
1783
|
+
return links;
|
|
1384
1784
|
}
|
|
1385
1785
|
function getEvidenceTags(node) {
|
|
1386
1786
|
const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : null;
|
|
@@ -1406,7 +1806,8 @@ async function computeTaggedEvidenceCount(args) {
|
|
|
1406
1806
|
};
|
|
1407
1807
|
}
|
|
1408
1808
|
async function computeContradictionCounts(ctx, beliefNodeId) {
|
|
1409
|
-
const
|
|
1809
|
+
const contradictionDb = ctx.db;
|
|
1810
|
+
const contradictions = await contradictionDb.query("contradictions").withIndex("by_beliefId", (q) => q.eq("beliefId", beliefNodeId)).collect();
|
|
1410
1811
|
return contradictions.reduce(
|
|
1411
1812
|
(counts, contradiction) => {
|
|
1412
1813
|
const status = contradiction.resolutionStatus ?? contradiction.status ?? "unresolved";
|
|
@@ -1442,18 +1843,16 @@ async function computeEvidenceFreshness(ctx, beliefNodeId, now = Date.now()) {
|
|
|
1442
1843
|
};
|
|
1443
1844
|
}
|
|
1444
1845
|
async function computeDependentBeliefCount(ctx, beliefNodeId) {
|
|
1445
|
-
const incomingEdges = await ctx
|
|
1846
|
+
const incomingEdges = await collectIncomingEdgeRows(ctx, beliefNodeId);
|
|
1446
1847
|
const dependencyEdges = incomingEdges.filter(
|
|
1447
|
-
(edge) => DEPENDENT_EDGE_TYPES.has(edge.edgeType)
|
|
1848
|
+
(edge) => edge.edgeType ? DEPENDENT_EDGE_TYPES.has(edge.edgeType) : false
|
|
1448
1849
|
);
|
|
1449
1850
|
if (dependencyEdges.length === 0) {
|
|
1450
1851
|
return 0;
|
|
1451
1852
|
}
|
|
1452
|
-
const dependentBeliefs = await Promise.all(
|
|
1453
|
-
dependencyEdges.map((edge) => ctx.db.get(edge.fromNodeId))
|
|
1454
|
-
);
|
|
1455
1853
|
const uniqueBeliefIds = /* @__PURE__ */ new Set();
|
|
1456
|
-
for (const
|
|
1854
|
+
for (const edge of dependencyEdges) {
|
|
1855
|
+
const node = await resolveEndpointNode(ctx, sourceEndpointRefs(edge));
|
|
1457
1856
|
if (node && node.nodeType === "belief" && node.status !== "archived" && node.status !== "deleted") {
|
|
1458
1857
|
uniqueBeliefIds.add(String(node._id));
|
|
1459
1858
|
}
|
|
@@ -1463,7 +1862,10 @@ async function computeDependentBeliefCount(ctx, beliefNodeId) {
|
|
|
1463
1862
|
async function snapshotEvidentialMetric(args) {
|
|
1464
1863
|
switch (args.metric) {
|
|
1465
1864
|
case "evidence_count": {
|
|
1466
|
-
const count = await computeEvidenceCountMetric(
|
|
1865
|
+
const count = await computeEvidenceCountMetric(
|
|
1866
|
+
args.ctx,
|
|
1867
|
+
args.beliefNodeId
|
|
1868
|
+
);
|
|
1467
1869
|
return {
|
|
1468
1870
|
metric: args.metric,
|
|
1469
1871
|
value: count,
|
|
@@ -1471,7 +1873,10 @@ async function snapshotEvidentialMetric(args) {
|
|
|
1471
1873
|
};
|
|
1472
1874
|
}
|
|
1473
1875
|
case "contradiction_status": {
|
|
1474
|
-
const counts = await computeContradictionCounts(
|
|
1876
|
+
const counts = await computeContradictionCounts(
|
|
1877
|
+
args.ctx,
|
|
1878
|
+
args.beliefNodeId
|
|
1879
|
+
);
|
|
1475
1880
|
return {
|
|
1476
1881
|
metric: args.metric,
|
|
1477
1882
|
value: counts.activeCount,
|
|
@@ -1491,7 +1896,10 @@ async function snapshotEvidentialMetric(args) {
|
|
|
1491
1896
|
};
|
|
1492
1897
|
}
|
|
1493
1898
|
case "dependent_count": {
|
|
1494
|
-
const count = await computeDependentBeliefCount(
|
|
1899
|
+
const count = await computeDependentBeliefCount(
|
|
1900
|
+
args.ctx,
|
|
1901
|
+
args.beliefNodeId
|
|
1902
|
+
);
|
|
1495
1903
|
return {
|
|
1496
1904
|
metric: args.metric,
|
|
1497
1905
|
value: count,
|
|
@@ -1507,7 +1915,9 @@ async function snapshotEvidentialMetric(args) {
|
|
|
1507
1915
|
}
|
|
1508
1916
|
}
|
|
1509
1917
|
async function evaluateBuiltInEvidentialContract(args) {
|
|
1510
|
-
const config = parseEvidentialEvaluatorConfig(
|
|
1918
|
+
const config = parseEvidentialEvaluatorConfig(
|
|
1919
|
+
args.contract.condition.evaluatorConfig
|
|
1920
|
+
);
|
|
1511
1921
|
const snapshot = await snapshotEvidentialMetric({
|
|
1512
1922
|
ctx: args.ctx,
|
|
1513
1923
|
beliefNodeId: args.belief._id,
|
|
@@ -1515,7 +1925,10 @@ async function evaluateBuiltInEvidentialContract(args) {
|
|
|
1515
1925
|
now: args.now
|
|
1516
1926
|
});
|
|
1517
1927
|
const comparisonSatisfied = snapshot.value !== null && compareMetricValue(config.operator, snapshot.value, config.threshold);
|
|
1518
|
-
const result =
|
|
1928
|
+
const result = resolveComparisonResult(
|
|
1929
|
+
args.contract.direction,
|
|
1930
|
+
comparisonSatisfied
|
|
1931
|
+
);
|
|
1519
1932
|
return {
|
|
1520
1933
|
result,
|
|
1521
1934
|
rationale: buildEvidentialRationale({
|
|
@@ -1535,57 +1948,66 @@ async function evaluateBuiltInEvidentialContract(args) {
|
|
|
1535
1948
|
}
|
|
1536
1949
|
};
|
|
1537
1950
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
"
|
|
1544
|
-
"
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
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
|
+
);
|
|
1549
1986
|
return {
|
|
1550
|
-
result
|
|
1551
|
-
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
|
+
}),
|
|
1552
1997
|
data: {
|
|
1553
1998
|
metric,
|
|
1554
|
-
observedValue
|
|
1999
|
+
observedValue,
|
|
1555
2000
|
operator: config.operator,
|
|
1556
2001
|
threshold: config.threshold,
|
|
1557
2002
|
unit: config.unit
|
|
1558
2003
|
}
|
|
1559
2004
|
};
|
|
1560
|
-
}
|
|
1561
|
-
const comparisonSatisfied = compareMetricValue(
|
|
1562
|
-
config.operator,
|
|
1563
|
-
observedValue,
|
|
1564
|
-
config.threshold
|
|
1565
|
-
);
|
|
1566
|
-
const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
|
|
1567
|
-
return {
|
|
1568
|
-
result,
|
|
1569
|
-
rationale: buildComparisonRationale({
|
|
1570
|
-
label: metric ?? "metric",
|
|
1571
|
-
observedValue,
|
|
1572
|
-
operator: config.operator,
|
|
1573
|
-
threshold: config.threshold,
|
|
1574
|
-
comparisonSatisfied,
|
|
1575
|
-
result,
|
|
1576
|
-
unit: config.unit
|
|
1577
|
-
}),
|
|
1578
|
-
data: {
|
|
1579
|
-
metric,
|
|
1580
|
-
observedValue,
|
|
1581
|
-
operator: config.operator,
|
|
1582
|
-
threshold: config.threshold,
|
|
1583
|
-
unit: config.unit
|
|
1584
|
-
}
|
|
1585
|
-
};
|
|
2005
|
+
});
|
|
1586
2006
|
}
|
|
1587
2007
|
async function evaluateReferenceCheckCounterContract(args) {
|
|
1588
|
-
const config = parseReferenceCheckCounterConfig(
|
|
2008
|
+
const config = parseReferenceCheckCounterConfig(
|
|
2009
|
+
args.contract.condition.evaluatorConfig
|
|
2010
|
+
);
|
|
1589
2011
|
const input = getEvaluatorInputRecord(args.inputData, "referenceCheckData");
|
|
1590
2012
|
const tag = typeof input.tag === "string" && input.tag.trim().length > 0 ? input.tag.trim() : config.tag;
|
|
1591
2013
|
const snapshot = await computeTaggedEvidenceCount({
|
|
@@ -1599,7 +2021,10 @@ async function evaluateReferenceCheckCounterContract(args) {
|
|
|
1599
2021
|
snapshot.count,
|
|
1600
2022
|
config.threshold
|
|
1601
2023
|
);
|
|
1602
|
-
const result = resolveComparisonResult(
|
|
2024
|
+
const result = resolveComparisonResult(
|
|
2025
|
+
args.contract.direction,
|
|
2026
|
+
comparisonSatisfied
|
|
2027
|
+
);
|
|
1603
2028
|
return {
|
|
1604
2029
|
result,
|
|
1605
2030
|
rationale: buildComparisonRationale({
|
|
@@ -1621,130 +2046,167 @@ async function evaluateReferenceCheckCounterContract(args) {
|
|
|
1621
2046
|
}
|
|
1622
2047
|
};
|
|
1623
2048
|
}
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
"temporal_deadline requires contract.deadline to be set to a finite timestamp."
|
|
1628
|
-
);
|
|
1629
|
-
}
|
|
1630
|
-
const config = parseTemporalDeadlineConfig(args.contract.condition.evaluatorConfig);
|
|
1631
|
-
const input = getEvaluatorInputRecord(args.inputData, "temporalData");
|
|
1632
|
-
const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
|
|
1633
|
-
const completedAt = pickFiniteNumber(input, [
|
|
1634
|
-
"completedAt",
|
|
1635
|
-
"observedAt",
|
|
1636
|
-
"satisfiedAt",
|
|
1637
|
-
"achievedAt"
|
|
1638
|
-
]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
|
|
1639
|
-
const completed = input.completed === true || config.completed === true || completedAt !== void 0;
|
|
1640
|
-
if (completed) {
|
|
1641
|
-
if (completedAt !== void 0 && completedAt > args.contract.deadline) {
|
|
1642
|
-
return {
|
|
1643
|
-
result: "expired",
|
|
1644
|
-
rationale: `${label} completed at ${completedAt}, after deadline ${args.contract.deadline}.`,
|
|
1645
|
-
data: {
|
|
1646
|
-
label,
|
|
1647
|
-
deadline: args.contract.deadline,
|
|
1648
|
-
completed: true,
|
|
1649
|
-
completedAt,
|
|
1650
|
-
missedDeadline: true,
|
|
1651
|
-
overdueByMs: completedAt - args.contract.deadline
|
|
1652
|
-
}
|
|
1653
|
-
};
|
|
1654
|
-
}
|
|
1655
|
-
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) {
|
|
1656
2052
|
return {
|
|
1657
|
-
result,
|
|
1658
|
-
rationale: `${label} completed
|
|
2053
|
+
result: "expired",
|
|
2054
|
+
rationale: `${label} completed at ${completedAt}, after deadline ${deadline}.`,
|
|
1659
2055
|
data: {
|
|
1660
2056
|
label,
|
|
1661
|
-
deadline
|
|
2057
|
+
deadline,
|
|
1662
2058
|
completed: true,
|
|
1663
|
-
completedAt
|
|
1664
|
-
missedDeadline:
|
|
2059
|
+
completedAt,
|
|
2060
|
+
missedDeadline: true,
|
|
2061
|
+
overdueByMs: completedAt - deadline
|
|
1665
2062
|
}
|
|
1666
2063
|
};
|
|
1667
2064
|
}
|
|
1668
|
-
|
|
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) {
|
|
1669
2081
|
return {
|
|
1670
2082
|
result: "expired",
|
|
1671
|
-
rationale: `${label} missed deadline ${
|
|
2083
|
+
rationale: `${label} missed deadline ${deadline}; temporal contract expired.`,
|
|
1672
2084
|
data: {
|
|
1673
2085
|
label,
|
|
1674
|
-
deadline
|
|
2086
|
+
deadline,
|
|
1675
2087
|
completed: false,
|
|
1676
|
-
overdueByMs:
|
|
2088
|
+
overdueByMs: context.now - deadline
|
|
1677
2089
|
}
|
|
1678
2090
|
};
|
|
1679
2091
|
}
|
|
1680
2092
|
return {
|
|
1681
2093
|
result: "inconclusive",
|
|
1682
|
-
rationale: `${label} is still before deadline ${
|
|
2094
|
+
rationale: `${label} is still before deadline ${deadline}; awaiting outcome.`,
|
|
1683
2095
|
data: {
|
|
1684
2096
|
label,
|
|
1685
|
-
deadline
|
|
2097
|
+
deadline,
|
|
1686
2098
|
completed: false,
|
|
1687
|
-
timeRemainingMs:
|
|
2099
|
+
timeRemainingMs: deadline - context.now
|
|
1688
2100
|
}
|
|
1689
2101
|
};
|
|
1690
2102
|
}
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
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
|
+
);
|
|
1699
2181
|
return {
|
|
1700
|
-
result
|
|
1701
|
-
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
|
+
}),
|
|
1702
2192
|
data: {
|
|
1703
2193
|
subject,
|
|
1704
2194
|
subjectValue,
|
|
1705
2195
|
benchmark,
|
|
1706
2196
|
benchmarkValue,
|
|
2197
|
+
differentialPercent,
|
|
1707
2198
|
operator: config.operator,
|
|
1708
2199
|
threshold: config.threshold
|
|
1709
2200
|
}
|
|
1710
2201
|
};
|
|
1711
|
-
}
|
|
1712
|
-
if (benchmarkValue === 0) {
|
|
1713
|
-
throw new Error(
|
|
1714
|
-
"market_index_comparator cannot compare against a zero benchmark value."
|
|
1715
|
-
);
|
|
1716
|
-
}
|
|
1717
|
-
const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
|
|
1718
|
-
const comparisonSatisfied = compareMetricValue(
|
|
1719
|
-
config.operator,
|
|
1720
|
-
differentialPercent,
|
|
1721
|
-
config.threshold
|
|
1722
|
-
);
|
|
1723
|
-
const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
|
|
1724
|
-
return {
|
|
1725
|
-
result,
|
|
1726
|
-
rationale: buildComparisonRationale({
|
|
1727
|
-
label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
|
|
1728
|
-
observedValue: differentialPercent,
|
|
1729
|
-
operator: config.operator,
|
|
1730
|
-
threshold: config.threshold,
|
|
1731
|
-
comparisonSatisfied,
|
|
1732
|
-
result,
|
|
1733
|
-
unit: "%"
|
|
1734
|
-
}),
|
|
1735
|
-
data: {
|
|
1736
|
-
subject,
|
|
1737
|
-
subjectValue,
|
|
1738
|
-
benchmark,
|
|
1739
|
-
benchmarkValue,
|
|
1740
|
-
differentialPercent,
|
|
1741
|
-
operator: config.operator,
|
|
1742
|
-
threshold: config.threshold
|
|
1743
|
-
}
|
|
1744
|
-
};
|
|
2202
|
+
});
|
|
1745
2203
|
}
|
|
1746
2204
|
var METRIC_COMPARATOR_EVALUATOR_NAMES = {
|
|
1747
|
-
evidentialAliases: /* @__PURE__ */ new Set([
|
|
2205
|
+
evidentialAliases: /* @__PURE__ */ new Set([
|
|
2206
|
+
"evidential",
|
|
2207
|
+
"built_in_evidential",
|
|
2208
|
+
"builtin_evidential"
|
|
2209
|
+
]),
|
|
1748
2210
|
metricChecker: "metric_checker",
|
|
1749
2211
|
referenceCheckCounter: "reference_check_counter",
|
|
1750
2212
|
temporalDeadline: "temporal_deadline",
|
|
@@ -1752,6 +2214,8 @@ var METRIC_COMPARATOR_EVALUATOR_NAMES = {
|
|
|
1752
2214
|
};
|
|
1753
2215
|
|
|
1754
2216
|
// src/evaluators/shared.ts
|
|
2217
|
+
var WINDOWS_PATH_SEPARATORS = /\\/g;
|
|
2218
|
+
var LEADING_DOT_SLASH = /^\.\//;
|
|
1755
2219
|
function asArray(value) {
|
|
1756
2220
|
return Array.isArray(value) ? value : [];
|
|
1757
2221
|
}
|
|
@@ -1793,7 +2257,7 @@ function extractTextCandidates(value) {
|
|
|
1793
2257
|
return Array.from(new Set(candidates));
|
|
1794
2258
|
}
|
|
1795
2259
|
function normalizeFilePath(value) {
|
|
1796
|
-
return value.replace(
|
|
2260
|
+
return value.replace(WINDOWS_PATH_SEPARATORS, "/").replace(LEADING_DOT_SLASH, "");
|
|
1797
2261
|
}
|
|
1798
2262
|
function normalizeToolResultEnvelope(value) {
|
|
1799
2263
|
const record = asRecord(value);
|
|
@@ -1847,7 +2311,7 @@ function somePatternMatches(filePath, patterns) {
|
|
|
1847
2311
|
return patterns.some((pattern) => patternMatchesPath(filePath, pattern));
|
|
1848
2312
|
}
|
|
1849
2313
|
|
|
1850
|
-
// src/evaluators/
|
|
2314
|
+
// src/evaluators/lint-checker-evaluator.ts
|
|
1851
2315
|
function parseConfig(condition) {
|
|
1852
2316
|
const record = asRecord(condition.evaluatorConfig);
|
|
1853
2317
|
if (!record) {
|
|
@@ -1919,7 +2383,10 @@ var lintCheckerEvaluator = {
|
|
|
1919
2383
|
}
|
|
1920
2384
|
const envelope = normalizeToolResultEnvelope(args.resultData);
|
|
1921
2385
|
const exitCode = asNumber(envelope.exitCode);
|
|
1922
|
-
const matchedDiagnostics = getMatchedDiagnostics(
|
|
2386
|
+
const matchedDiagnostics = getMatchedDiagnostics(
|
|
2387
|
+
args.contract,
|
|
2388
|
+
args.resultData
|
|
2389
|
+
);
|
|
1923
2390
|
if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
|
|
1924
2391
|
return {
|
|
1925
2392
|
result: "inconclusive",
|
|
@@ -1945,7 +2412,7 @@ var lintCheckerEvaluator = {
|
|
|
1945
2412
|
}
|
|
1946
2413
|
};
|
|
1947
2414
|
|
|
1948
|
-
// src/evaluators/
|
|
2415
|
+
// src/evaluators/sentry-checker-evaluator.ts
|
|
1949
2416
|
function parseConfig2(condition) {
|
|
1950
2417
|
const record = asRecord(condition.evaluatorConfig);
|
|
1951
2418
|
if (!record) {
|
|
@@ -2030,7 +2497,7 @@ var sentryCheckerEvaluator = {
|
|
|
2030
2497
|
}
|
|
2031
2498
|
};
|
|
2032
2499
|
|
|
2033
|
-
// src/evaluators/
|
|
2500
|
+
// src/evaluators/test-runner-evaluator.ts
|
|
2034
2501
|
function parseConfig3(condition) {
|
|
2035
2502
|
const record = asRecord(condition.evaluatorConfig);
|
|
2036
2503
|
if (!record) {
|
|
@@ -2176,7 +2643,7 @@ var testRunnerEvaluator = {
|
|
|
2176
2643
|
}
|
|
2177
2644
|
};
|
|
2178
2645
|
|
|
2179
|
-
// src/evaluators/
|
|
2646
|
+
// src/evaluators/tsc-checker-evaluator.ts
|
|
2180
2647
|
function parseConfig4(condition) {
|
|
2181
2648
|
const record = asRecord(condition.evaluatorConfig);
|
|
2182
2649
|
if (!record) {
|
|
@@ -2261,7 +2728,10 @@ var tscCheckerEvaluator = {
|
|
|
2261
2728
|
}
|
|
2262
2729
|
const envelope = normalizeToolResultEnvelope(args.resultData);
|
|
2263
2730
|
const exitCode = asNumber(envelope.exitCode);
|
|
2264
|
-
const matchedDiagnostics = getMatchedDiagnostics2(
|
|
2731
|
+
const matchedDiagnostics = getMatchedDiagnostics2(
|
|
2732
|
+
args.contract,
|
|
2733
|
+
args.resultData
|
|
2734
|
+
);
|
|
2265
2735
|
if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
|
|
2266
2736
|
return {
|
|
2267
2737
|
result: "inconclusive",
|
|
@@ -2310,6 +2780,18 @@ var BUILT_IN_REFERENCE_CHECK_COUNTER2 = METRIC_COMPARATOR_EVALUATOR_NAMES.refere
|
|
|
2310
2780
|
var BUILT_IN_TEMPORAL_DEADLINE2 = METRIC_COMPARATOR_EVALUATOR_NAMES.temporalDeadline;
|
|
2311
2781
|
var BUILT_IN_MARKET_INDEX_COMPARATOR2 = METRIC_COMPARATOR_EVALUATOR_NAMES.marketIndexComparator;
|
|
2312
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
|
+
}
|
|
2313
2795
|
function clearEpistemicEvaluators() {
|
|
2314
2796
|
evaluatorRegistry.clear();
|
|
2315
2797
|
ensureBuiltInEvaluators();
|
|
@@ -2402,7 +2884,10 @@ async function executeContractEvaluation(args) {
|
|
|
2402
2884
|
rationale: `No epistemic evaluator registered for "${args.contract.condition.evaluator}".`
|
|
2403
2885
|
};
|
|
2404
2886
|
}
|
|
2405
|
-
const confidenceBefore =
|
|
2887
|
+
const confidenceBefore = confidenceSeed({
|
|
2888
|
+
beliefConfidence: args.belief.confidence,
|
|
2889
|
+
currentConfidence: args.currentConfidence
|
|
2890
|
+
});
|
|
2406
2891
|
const modulationPlan = deriveContractModulationPlan({
|
|
2407
2892
|
currentConfidence: confidenceBefore,
|
|
2408
2893
|
modulation: args.contract.modulation,
|
|
@@ -2442,16 +2927,16 @@ async function executeContractEvaluation(args) {
|
|
|
2442
2927
|
modulationRationale: evaluation.rationale,
|
|
2443
2928
|
topicId: args.contract.topicId
|
|
2444
2929
|
});
|
|
2445
|
-
const nextStatus = deriveContractStatus(
|
|
2446
|
-
|
|
2447
|
-
args.contract.
|
|
2448
|
-
{
|
|
2449
|
-
status: nextStatus,
|
|
2450
|
-
lastEvaluatedAt: args.now,
|
|
2451
|
-
evaluationCount: (args.contract.evaluationCount ?? 0) + 1,
|
|
2452
|
-
updatedAt: args.now
|
|
2453
|
-
}
|
|
2930
|
+
const nextStatus = deriveContractStatus(
|
|
2931
|
+
evaluation.result,
|
|
2932
|
+
args.contract.status
|
|
2454
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
|
+
});
|
|
2455
2940
|
return {
|
|
2456
2941
|
evaluationId,
|
|
2457
2942
|
result: evaluation.result,
|
|
@@ -2536,7 +3021,8 @@ async function evaluateContractsForTriggerBatch(args) {
|
|
|
2536
3021
|
};
|
|
2537
3022
|
}
|
|
2538
3023
|
async function loadContractsForBelief(args) {
|
|
2539
|
-
|
|
3024
|
+
const rows = await args.ctx.db.query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
|
|
3025
|
+
return rows;
|
|
2540
3026
|
}
|
|
2541
3027
|
async function loadContractsForTrigger(args) {
|
|
2542
3028
|
const contracts = await loadContractsForBelief(args);
|
|
@@ -2571,6 +3057,24 @@ function resolveSchedulesForTrigger2(trigger) {
|
|
|
2571
3057
|
}
|
|
2572
3058
|
return /* @__PURE__ */ new Set(["event_driven"]);
|
|
2573
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
|
+
}
|
|
2574
3078
|
async function requireAuth(ctx) {
|
|
2575
3079
|
const userId = await getCurrentUserId(ctx);
|
|
2576
3080
|
if (!userId) {
|
|
@@ -2606,17 +3110,21 @@ async function requireTopicReadAccess(ctx, beliefs, userId) {
|
|
|
2606
3110
|
projectIds.add(belief.projectId);
|
|
2607
3111
|
}
|
|
2608
3112
|
for (const projectId of projectIds) {
|
|
2609
|
-
const hasAccess = await checkProjectAccess(
|
|
3113
|
+
const hasAccess = await checkProjectAccess(
|
|
3114
|
+
ctx,
|
|
3115
|
+
projectId,
|
|
3116
|
+
userId
|
|
3117
|
+
);
|
|
2610
3118
|
if (!hasAccess) {
|
|
2611
3119
|
throw new Error("Project access required.");
|
|
2612
3120
|
}
|
|
2613
3121
|
}
|
|
2614
3122
|
}
|
|
2615
3123
|
async function getContractByContractId(ctx, contractId) {
|
|
2616
|
-
return await ctx.
|
|
3124
|
+
return await contractTables(ctx).query("epistemicContracts").withIndex("by_contractId", (q) => q.eq("contractId", contractId)).first();
|
|
2617
3125
|
}
|
|
2618
3126
|
async function getLatestEvaluation(ctx, contractId) {
|
|
2619
|
-
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);
|
|
2620
3128
|
return evaluations[0] ?? null;
|
|
2621
3129
|
}
|
|
2622
3130
|
var evaluateEvidenceCount = query({
|
|
@@ -2626,10 +3134,7 @@ var evaluateEvidenceCount = query({
|
|
|
2626
3134
|
returns: permissiveReturn,
|
|
2627
3135
|
handler: async (ctx, args) => {
|
|
2628
3136
|
const userId = await requireAuth(ctx);
|
|
2629
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2630
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2631
|
-
throw new Error("Belief not found.");
|
|
2632
|
-
}
|
|
3137
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2633
3138
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2634
3139
|
return await computeEvidenceCountMetric(ctx, args.beliefNodeId);
|
|
2635
3140
|
}
|
|
@@ -2641,10 +3146,7 @@ var evaluateContradictionStatus = query({
|
|
|
2641
3146
|
returns: permissiveReturn,
|
|
2642
3147
|
handler: async (ctx, args) => {
|
|
2643
3148
|
const userId = await requireAuth(ctx);
|
|
2644
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2645
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2646
|
-
throw new Error("Belief not found.");
|
|
2647
|
-
}
|
|
3149
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2648
3150
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2649
3151
|
return await computeContradictionCounts(ctx, args.beliefNodeId);
|
|
2650
3152
|
}
|
|
@@ -2656,10 +3158,7 @@ var evaluateEdgeFreshness = query({
|
|
|
2656
3158
|
returns: permissiveReturn,
|
|
2657
3159
|
handler: async (ctx, args) => {
|
|
2658
3160
|
const userId = await requireAuth(ctx);
|
|
2659
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2660
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2661
|
-
throw new Error("Belief not found.");
|
|
2662
|
-
}
|
|
3161
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2663
3162
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2664
3163
|
return await computeEvidenceFreshness(ctx, args.beliefNodeId);
|
|
2665
3164
|
}
|
|
@@ -2671,10 +3170,7 @@ var evaluateDependentBeliefCount = query({
|
|
|
2671
3170
|
returns: permissiveReturn,
|
|
2672
3171
|
handler: async (ctx, args) => {
|
|
2673
3172
|
const userId = await requireAuth(ctx);
|
|
2674
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2675
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2676
|
-
throw new Error("Belief not found.");
|
|
2677
|
-
}
|
|
3173
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2678
3174
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2679
3175
|
return await computeDependentBeliefCount(ctx, args.beliefNodeId);
|
|
2680
3176
|
}
|
|
@@ -2738,10 +3234,7 @@ var createEpistemicContract = mutation({
|
|
|
2738
3234
|
ctx,
|
|
2739
3235
|
args.authenticatedUserId
|
|
2740
3236
|
);
|
|
2741
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2742
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2743
|
-
throw new Error("Belief not found.");
|
|
2744
|
-
}
|
|
3237
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2745
3238
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2746
3239
|
const now = Date.now();
|
|
2747
3240
|
const contractId = generateGlobalId();
|
|
@@ -2796,10 +3289,10 @@ var evaluateContract = mutation({
|
|
|
2796
3289
|
if (contract.status === "archived") {
|
|
2797
3290
|
throw new Error("Archived contracts cannot be evaluated.");
|
|
2798
3291
|
}
|
|
2799
|
-
const belief =
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
3292
|
+
const belief = assertBeliefNode(
|
|
3293
|
+
await ctx.db.get(contract.beliefNodeId),
|
|
3294
|
+
"Belief not found for contract."
|
|
3295
|
+
);
|
|
2803
3296
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2804
3297
|
const evaluation = await executeContractEvaluation({
|
|
2805
3298
|
ctx,
|
|
@@ -2837,14 +3330,11 @@ var evaluateEngineeringContracts = mutation({
|
|
|
2837
3330
|
ctx,
|
|
2838
3331
|
args.authenticatedUserId
|
|
2839
3332
|
);
|
|
2840
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2841
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2842
|
-
throw new Error("Belief not found.");
|
|
2843
|
-
}
|
|
3333
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2844
3334
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2845
3335
|
const trigger = args.trigger ?? "event_driven";
|
|
2846
3336
|
const allowedSchedules = resolveSchedulesForTrigger2(
|
|
2847
|
-
trigger
|
|
3337
|
+
normalizeEngineeringTrigger(trigger)
|
|
2848
3338
|
);
|
|
2849
3339
|
const payloadByEvaluator = /* @__PURE__ */ new Map([
|
|
2850
3340
|
["test_runner", args.testOutput],
|
|
@@ -2923,10 +3413,7 @@ var evaluateContractsForTrigger = mutation({
|
|
|
2923
3413
|
ctx,
|
|
2924
3414
|
args.authenticatedUserId
|
|
2925
3415
|
);
|
|
2926
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2927
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2928
|
-
throw new Error("Belief not found.");
|
|
2929
|
-
}
|
|
3416
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2930
3417
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2931
3418
|
return await evaluateContractsForTriggerBatch({
|
|
2932
3419
|
ctx,
|
|
@@ -2949,10 +3436,7 @@ var processContractEvaluationOverflow = internalMutation({
|
|
|
2949
3436
|
},
|
|
2950
3437
|
returns: permissiveReturn,
|
|
2951
3438
|
handler: async (ctx, args) => {
|
|
2952
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2953
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2954
|
-
throw new Error("Belief not found.");
|
|
2955
|
-
}
|
|
3439
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2956
3440
|
return await evaluateContractsForTriggerBatch({
|
|
2957
3441
|
ctx,
|
|
2958
3442
|
belief,
|
|
@@ -2991,15 +3475,9 @@ var getContractStatus = query({
|
|
|
2991
3475
|
const contract = await getContractByContractId(ctx, args.contractId);
|
|
2992
3476
|
contracts = contract ? [contract] : [];
|
|
2993
3477
|
} else if (args.beliefNodeId) {
|
|
2994
|
-
const belief = await ctx.db.get(args.beliefNodeId);
|
|
2995
|
-
if (!belief || belief.nodeType !== "belief") {
|
|
2996
|
-
throw new Error("Belief not found.");
|
|
2997
|
-
}
|
|
3478
|
+
const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
|
|
2998
3479
|
await requireBeliefProjectAccess(ctx, belief, userId);
|
|
2999
|
-
contracts = await ctx.
|
|
3000
|
-
"by_belief",
|
|
3001
|
-
(q) => q.eq("beliefNodeId", args.beliefNodeId)
|
|
3002
|
-
).collect();
|
|
3480
|
+
contracts = await contractTables(ctx).query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
|
|
3003
3481
|
}
|
|
3004
3482
|
if (contracts.length > 0) {
|
|
3005
3483
|
const contractBeliefDocs = await Promise.all(
|
|
@@ -3007,15 +3485,14 @@ var getContractStatus = query({
|
|
|
3007
3485
|
);
|
|
3008
3486
|
const contractBeliefs = [];
|
|
3009
3487
|
for (const belief of contractBeliefDocs) {
|
|
3010
|
-
|
|
3011
|
-
throw new Error("Belief not found.");
|
|
3012
|
-
}
|
|
3013
|
-
contractBeliefs.push(belief);
|
|
3488
|
+
contractBeliefs.push(assertBeliefNode(belief));
|
|
3014
3489
|
}
|
|
3015
3490
|
await requireTopicReadAccess(ctx, contractBeliefs, userId);
|
|
3016
3491
|
}
|
|
3017
3492
|
if (args.status) {
|
|
3018
|
-
contracts = contracts.filter(
|
|
3493
|
+
contracts = contracts.filter(
|
|
3494
|
+
(contract) => contract.status === args.status
|
|
3495
|
+
);
|
|
3019
3496
|
}
|
|
3020
3497
|
const rows = await Promise.all(
|
|
3021
3498
|
contracts.map(async (contract) => ({
|
|
@@ -3034,21 +3511,22 @@ var getContractCoverage = query({
|
|
|
3034
3511
|
},
|
|
3035
3512
|
returns: permissiveReturn,
|
|
3036
3513
|
handler: async (ctx, args) => {
|
|
3037
|
-
const contracts = await ctx.
|
|
3514
|
+
const contracts = await contractTables(ctx).query("epistemicContracts").withIndex("by_topic", (q) => q.eq("topicId", args.topicId)).collect();
|
|
3038
3515
|
const userId = await resolveAuthenticatedUserId(
|
|
3039
3516
|
ctx,
|
|
3040
3517
|
args.authenticatedUserId
|
|
3041
3518
|
);
|
|
3042
|
-
const
|
|
3519
|
+
const beliefRows = await ctx.db.query("epistemicNodes").withIndex(
|
|
3043
3520
|
"by_topic_type",
|
|
3044
3521
|
(q) => q.eq("topicId", args.topicId).eq("nodeType", "belief")
|
|
3045
3522
|
).collect();
|
|
3523
|
+
const beliefs = beliefRows.map((belief) => assertBeliefNode(belief));
|
|
3046
3524
|
await requireTopicReadAccess(ctx, beliefs, userId);
|
|
3047
3525
|
const recentEvaluationLimit = Math.max(
|
|
3048
3526
|
0,
|
|
3049
3527
|
Math.min(args.recentEvaluationLimit ?? 5, 25)
|
|
3050
3528
|
);
|
|
3051
|
-
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);
|
|
3052
3530
|
const contractBeliefIds = new Set(
|
|
3053
3531
|
contracts.filter((contract) => contract.status !== "archived").map((contract) => String(contract.beliefNodeId))
|
|
3054
3532
|
);
|
|
@@ -3071,6 +3549,23 @@ function inheritContractsForFork(contracts, args) {
|
|
|
3071
3549
|
return contracts.filter((contract) => contract.status !== "archived").map((contract) => createInheritedContractRecord(contract, args));
|
|
3072
3550
|
}
|
|
3073
3551
|
|
|
3074
|
-
|
|
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 };
|
|
3075
3570
|
//# sourceMappingURL=epistemicContracts.js.map
|
|
3076
3571
|
//# sourceMappingURL=epistemicContracts.js.map
|