@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,14 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { normalizeTupleContradictionPolicy, mkOpinion, conditionalDeduction, project, dampedDependencyCascade, hasProjectedOpinionChanged, confidenceFromSL, detectTupleContradiction, evaluateTupleContradictionTransition, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, readOpinionFromRecord, deriveContractModulationPlan, deriveContractStatus, parseEvidentialEvaluatorConfig, compareMetricValue, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, resolveComparisonResult, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig } from '@lucern/confidence';
|
|
1
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
2
|
+
import { componentsGeneric, internalMutationGeneric } from 'convex/server';
|
|
4
3
|
import '@lucern/access-control/audience';
|
|
5
4
|
import '@lucern/access-control/auth';
|
|
6
|
-
import {
|
|
5
|
+
import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
|
|
6
|
+
import { normalizeTupleContradictionPolicy, mkOpinion, conditionalDeduction, project, dampedDependencyCascade, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, confidenceFromSL, detectTupleContradiction, evaluateTupleContradictionTransition, readOpinionFromRecord, hasProjectedOpinionChanged, deriveContractModulationPlan, deriveContractStatus, parseEvidentialEvaluatorConfig, compareMetricValue, resolveComparisonResult, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig } from '@lucern/confidence';
|
|
7
|
+
import { v } from 'convex/values';
|
|
7
8
|
import '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
|
|
8
9
|
import { requireScopeWriteAccess } from '@lucern/access-control/access';
|
|
9
10
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
10
11
|
|
|
11
|
-
// src/
|
|
12
|
+
// src/convex.ts
|
|
13
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
14
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
15
|
+
);
|
|
16
|
+
var api = unsafeApi;
|
|
17
|
+
componentsGeneric();
|
|
18
|
+
var internal = unsafeApi;
|
|
19
|
+
var internalMutation = internalMutationGeneric;
|
|
20
|
+
|
|
21
|
+
// src/debug.ts
|
|
22
|
+
function isGraphPrimitiveDebugEnabled() {
|
|
23
|
+
const env = globalThis.process?.env;
|
|
24
|
+
return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
|
|
25
|
+
}
|
|
26
|
+
function debugGraphPrimitiveFallback(message, context) {
|
|
27
|
+
if (!isGraphPrimitiveDebugEnabled()) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
console.debug(message, context ?? {});
|
|
31
|
+
}
|
|
12
32
|
|
|
13
33
|
// src/beliefLifecycle.ts
|
|
14
34
|
var BELIEF_STATUS_VALUES = [
|
|
@@ -130,22 +150,6 @@ function promoteBeliefStatusAfterScoring(status, opts) {
|
|
|
130
150
|
}
|
|
131
151
|
return status;
|
|
132
152
|
}
|
|
133
|
-
var api = anyApi;
|
|
134
|
-
componentsGeneric();
|
|
135
|
-
var internal = anyApi;
|
|
136
|
-
var internalMutation = internalMutationGeneric;
|
|
137
|
-
|
|
138
|
-
// src/debug.ts
|
|
139
|
-
function isGraphPrimitiveDebugEnabled() {
|
|
140
|
-
const env = globalThis.process?.env;
|
|
141
|
-
return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
|
|
142
|
-
}
|
|
143
|
-
function debugGraphPrimitiveFallback(message, context) {
|
|
144
|
-
if (!isGraphPrimitiveDebugEnabled()) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
console.debug(message, context ?? {});
|
|
148
|
-
}
|
|
149
153
|
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
150
154
|
async function resolveTopicNodeScopeOrNull(ctx, ref) {
|
|
151
155
|
if (!ctx?.db || typeof ctx.db.query !== "function") {
|
|
@@ -180,13 +184,15 @@ function asMappedProjectId(topic) {
|
|
|
180
184
|
if (!topic) {
|
|
181
185
|
return;
|
|
182
186
|
}
|
|
183
|
-
const directLegacyProjectId = normalizeScopeValue(
|
|
187
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
188
|
+
topic[LEGACY_SCOPE_FIELD]
|
|
189
|
+
);
|
|
184
190
|
if (directLegacyProjectId) {
|
|
185
191
|
return directLegacyProjectId;
|
|
186
192
|
}
|
|
187
193
|
const metadata = topic.metadata || {};
|
|
188
194
|
const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
189
|
-
return candidate ? candidate : void 0;
|
|
195
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
190
196
|
}
|
|
191
197
|
function normalizeScopeValue(value) {
|
|
192
198
|
if (typeof value !== "string") {
|
|
@@ -211,8 +217,9 @@ function pickPrimaryTopic(candidates) {
|
|
|
211
217
|
})[0];
|
|
212
218
|
}
|
|
213
219
|
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
220
|
+
const query = ctx.db.query("topics");
|
|
214
221
|
try {
|
|
215
|
-
return await
|
|
222
|
+
return await query.withIndex(
|
|
216
223
|
"by_graph_scope_project",
|
|
217
224
|
(q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
|
|
218
225
|
).collect();
|
|
@@ -224,7 +231,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
|
224
231
|
scopeId
|
|
225
232
|
}
|
|
226
233
|
);
|
|
227
|
-
const topics = await
|
|
234
|
+
const topics = await query.collect();
|
|
228
235
|
return topics.filter((topic) => {
|
|
229
236
|
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
230
237
|
const mappedProjectId = asMappedProjectId(topic);
|
|
@@ -280,137 +287,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
|
280
287
|
let current = topic;
|
|
281
288
|
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
282
289
|
current = await ctx.db.get(current.parentTopicId);
|
|
283
|
-
if (!current)
|
|
290
|
+
if (!current) {
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
284
293
|
if (!tenantId) {
|
|
285
294
|
tenantId = normalizeScopeValue(current.tenantId);
|
|
286
295
|
}
|
|
287
296
|
if (!workspaceId) {
|
|
288
297
|
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
289
298
|
}
|
|
290
|
-
if (tenantId && workspaceId)
|
|
299
|
+
if (tenantId && workspaceId) {
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
291
302
|
}
|
|
292
303
|
return { tenantId, workspaceId };
|
|
293
304
|
}
|
|
294
305
|
async function resolveTopicProjectScope(ctx, args) {
|
|
295
306
|
if (args.topicId) {
|
|
296
|
-
|
|
297
|
-
try {
|
|
298
|
-
topic = await ctx.db.get(
|
|
299
|
-
args.topicId
|
|
300
|
-
);
|
|
301
|
-
} catch (error) {
|
|
302
|
-
debugGraphPrimitiveFallback(
|
|
303
|
-
"[topicScope] Failed to load topic by direct id",
|
|
304
|
-
{
|
|
305
|
-
error,
|
|
306
|
-
topicId: args.topicId
|
|
307
|
-
}
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
if (!topic) {
|
|
311
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
312
|
-
}
|
|
313
|
-
if (!topic) {
|
|
314
|
-
topic = pickPrimaryTopic(
|
|
315
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
316
|
-
) ?? null;
|
|
317
|
-
}
|
|
318
|
-
if (!topic) {
|
|
319
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
320
|
-
ctx,
|
|
321
|
-
String(args.topicId)
|
|
322
|
-
);
|
|
323
|
-
if (nodeScope) {
|
|
324
|
-
return nodeScope;
|
|
325
|
-
}
|
|
326
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
327
|
-
}
|
|
328
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
329
|
-
const mapped = asMappedProjectId(topic);
|
|
330
|
-
if (mapped) {
|
|
331
|
-
return {
|
|
332
|
-
topicId: topic._id,
|
|
333
|
-
projectId: mapped,
|
|
334
|
-
tenantId: inherited.tenantId,
|
|
335
|
-
workspaceId: inherited.workspaceId,
|
|
336
|
-
source: "topic"
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
return {
|
|
340
|
-
topicId: topic._id,
|
|
341
|
-
tenantId: inherited.tenantId,
|
|
342
|
-
workspaceId: inherited.workspaceId,
|
|
343
|
-
source: "topic"
|
|
344
|
-
};
|
|
307
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
345
308
|
}
|
|
346
309
|
if (args.projectId) {
|
|
347
|
-
|
|
348
|
-
try {
|
|
349
|
-
directTopic = await ctx.db.get(
|
|
350
|
-
args.projectId
|
|
351
|
-
);
|
|
352
|
-
} catch (error) {
|
|
353
|
-
debugGraphPrimitiveFallback(
|
|
354
|
-
"[topicScope] Failed to load direct project topic",
|
|
355
|
-
{
|
|
356
|
-
error,
|
|
357
|
-
projectId: args.projectId
|
|
358
|
-
}
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
if (directTopic) {
|
|
362
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
363
|
-
const mapped = asMappedProjectId(directTopic);
|
|
364
|
-
return {
|
|
365
|
-
topicId: directTopic._id,
|
|
366
|
-
projectId: mapped ?? args.projectId,
|
|
367
|
-
tenantId: inherited.tenantId,
|
|
368
|
-
workspaceId: inherited.workspaceId,
|
|
369
|
-
source: "topic_inferred"
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
373
|
-
if (directTopic) {
|
|
374
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
375
|
-
const mapped = asMappedProjectId(directTopic);
|
|
376
|
-
return {
|
|
377
|
-
topicId: directTopic._id,
|
|
378
|
-
projectId: mapped ?? args.projectId,
|
|
379
|
-
tenantId: inherited.tenantId,
|
|
380
|
-
workspaceId: inherited.workspaceId,
|
|
381
|
-
source: "topic_inferred"
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
385
|
-
const primary = pickPrimaryTopic(topics);
|
|
386
|
-
if (primary) {
|
|
387
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
388
|
-
return {
|
|
389
|
-
topicId: primary._id,
|
|
390
|
-
projectId: args.projectId,
|
|
391
|
-
tenantId: inherited.tenantId,
|
|
392
|
-
workspaceId: inherited.workspaceId,
|
|
393
|
-
source: "project_mapped_topic"
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
397
|
-
ctx,
|
|
398
|
-
String(args.projectId)
|
|
399
|
-
);
|
|
400
|
-
if (nodeScope) {
|
|
401
|
-
return {
|
|
402
|
-
...nodeScope,
|
|
403
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
throw new Error(
|
|
407
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
408
|
-
);
|
|
310
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
409
311
|
}
|
|
410
312
|
throw new Error(
|
|
411
313
|
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
412
314
|
);
|
|
413
315
|
}
|
|
316
|
+
async function resolveScopeFromTopicId(ctx, topicId) {
|
|
317
|
+
const topic = await resolveTopicDocFromTopicId(ctx, topicId);
|
|
318
|
+
if (topic) {
|
|
319
|
+
return await buildTopicScope(ctx, topic, "topic");
|
|
320
|
+
}
|
|
321
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
|
|
322
|
+
if (nodeScope) {
|
|
323
|
+
return nodeScope;
|
|
324
|
+
}
|
|
325
|
+
throw new Error(`Topic not found: ${String(topicId)}`);
|
|
326
|
+
}
|
|
327
|
+
async function resolveTopicDocFromTopicId(ctx, topicId) {
|
|
328
|
+
const direct = await tryReadTopicDoc(ctx, topicId, {
|
|
329
|
+
failureLog: "[topicScope] Failed to load topic by direct id",
|
|
330
|
+
idLogKey: "topicId"
|
|
331
|
+
});
|
|
332
|
+
if (direct) {
|
|
333
|
+
return direct;
|
|
334
|
+
}
|
|
335
|
+
const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
|
|
336
|
+
if (hostTopic) {
|
|
337
|
+
return hostTopic;
|
|
338
|
+
}
|
|
339
|
+
return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
|
|
340
|
+
}
|
|
341
|
+
async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
|
|
342
|
+
const directTopic = await resolveDirectLegacyProjectTopic(
|
|
343
|
+
ctx,
|
|
344
|
+
legacyProjectId
|
|
345
|
+
);
|
|
346
|
+
if (directTopic) {
|
|
347
|
+
return await buildTopicScope(ctx, directTopic, "topic_inferred", {
|
|
348
|
+
fallbackProjectId: legacyProjectId
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
const primary = pickPrimaryTopic(
|
|
352
|
+
await findTopicsByScopeAlias(ctx, legacyProjectId)
|
|
353
|
+
);
|
|
354
|
+
if (primary) {
|
|
355
|
+
return await buildTopicScope(ctx, primary, "project_mapped_topic", {
|
|
356
|
+
fallbackProjectId: legacyProjectId
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
|
|
360
|
+
if (nodeScope) {
|
|
361
|
+
return {
|
|
362
|
+
...nodeScope,
|
|
363
|
+
projectId: nodeScope.projectId ?? legacyProjectId
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
throw new Error(
|
|
367
|
+
`Legacy project scope ${legacyProjectId} has no mapped topic.`
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
|
|
371
|
+
const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
|
|
372
|
+
failureLog: "[topicScope] Failed to load direct project topic",
|
|
373
|
+
idLogKey: "projectId"
|
|
374
|
+
});
|
|
375
|
+
return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
|
|
376
|
+
}
|
|
377
|
+
async function tryReadTopicDoc(ctx, id, log) {
|
|
378
|
+
try {
|
|
379
|
+
return await ctx.db.get(id);
|
|
380
|
+
} catch (error) {
|
|
381
|
+
debugGraphPrimitiveFallback(log.failureLog, {
|
|
382
|
+
error,
|
|
383
|
+
[log.idLogKey]: id
|
|
384
|
+
});
|
|
385
|
+
return null;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
async function buildTopicScope(ctx, topic, source, options = {}) {
|
|
389
|
+
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
390
|
+
const mapped = asMappedProjectId(topic);
|
|
391
|
+
return {
|
|
392
|
+
topicId: topic._id,
|
|
393
|
+
...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
|
|
394
|
+
tenantId: inherited.tenantId,
|
|
395
|
+
workspaceId: inherited.workspaceId,
|
|
396
|
+
source
|
|
397
|
+
};
|
|
398
|
+
}
|
|
414
399
|
({
|
|
415
400
|
projectId: v.optional(v.string()),
|
|
416
401
|
topicId: v.optional(v.string())
|
|
@@ -478,9 +463,10 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
|
|
|
478
463
|
if (resolved.tenantId || resolved.workspaceId) {
|
|
479
464
|
return resolved;
|
|
480
465
|
}
|
|
481
|
-
|
|
466
|
+
const topicId = normalizeScopeValue2(node.topicId);
|
|
467
|
+
if (topicId) {
|
|
482
468
|
const topicScope = await resolveTopicProjectScope(ctx, {
|
|
483
|
-
topicId
|
|
469
|
+
topicId
|
|
484
470
|
});
|
|
485
471
|
return {
|
|
486
472
|
...resolved,
|
|
@@ -500,8 +486,6 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
|
|
|
500
486
|
}
|
|
501
487
|
return resolved;
|
|
502
488
|
}
|
|
503
|
-
|
|
504
|
-
// src/epistemicBeliefs.helpers.ts
|
|
505
489
|
v.id("epistemicNodes");
|
|
506
490
|
var DEFAULT_CONFIDENCE_POLICY = {
|
|
507
491
|
scoringMode: "after_worktree",
|
|
@@ -581,7 +565,10 @@ function resolveBeliefStatus(node, metadata) {
|
|
|
581
565
|
});
|
|
582
566
|
}
|
|
583
567
|
async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
|
|
584
|
-
const clusterMembership = await ctx.db.query("worktreeBeliefCluster").withIndex(
|
|
568
|
+
const clusterMembership = await ctx.db.query("worktreeBeliefCluster").withIndex(
|
|
569
|
+
"by_belief",
|
|
570
|
+
(q) => q.eq("beliefId", beliefNodeId)
|
|
571
|
+
).collect();
|
|
585
572
|
for (const membership of clusterMembership) {
|
|
586
573
|
const worktree = await ctx.db.get(membership.worktreeId);
|
|
587
574
|
if (worktree?.status === "completed" || worktree?.status === "merged") {
|
|
@@ -592,7 +579,10 @@ async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
|
|
|
592
579
|
}
|
|
593
580
|
async function getActiveConfidencePolicy(ctx) {
|
|
594
581
|
try {
|
|
595
|
-
const activeConfig = await ctx.db.query("logicSprintScoring").withIndex(
|
|
582
|
+
const activeConfig = await ctx.db.query("logicSprintScoring").withIndex(
|
|
583
|
+
"by_active",
|
|
584
|
+
(q) => q.eq("isActive", true)
|
|
585
|
+
).first();
|
|
596
586
|
return {
|
|
597
587
|
scoringMode: activeConfig?.confidencePolicy === "always" ? "always" : DEFAULT_CONFIDENCE_POLICY.scoringMode,
|
|
598
588
|
tupleContradiction: normalizeTupleContradictionPolicy(
|
|
@@ -745,7 +735,7 @@ var dependsOnPropagationSpec = {
|
|
|
745
735
|
description: "Structural gating. Textbook conditional deduction when edge conditionals exist, otherwise damped dependency cascade through downstream chains."
|
|
746
736
|
};
|
|
747
737
|
|
|
748
|
-
// src/edges/
|
|
738
|
+
// src/edges/derived-from.ts
|
|
749
739
|
var derivedFromPropagationSpec = {
|
|
750
740
|
edgeType: "derived_from",
|
|
751
741
|
direction: "incoming",
|
|
@@ -798,7 +788,7 @@ var informsPropagationSpec = {
|
|
|
798
788
|
description: "Evidence-bearing influence. Informs can chain through the graph with light per-hop damping."
|
|
799
789
|
};
|
|
800
790
|
|
|
801
|
-
// src/edges/
|
|
791
|
+
// src/edges/propagation-types.ts
|
|
802
792
|
function isPropagationTraversalDirection(direction) {
|
|
803
793
|
return direction === "outgoing" || direction === "incoming";
|
|
804
794
|
}
|
|
@@ -871,6 +861,9 @@ var testsPropagationSpec = {
|
|
|
871
861
|
};
|
|
872
862
|
|
|
873
863
|
// src/edges/index.ts
|
|
864
|
+
var canContinueTransitively2 = canContinueTransitively;
|
|
865
|
+
var canTraverseHop2 = canTraverseHop;
|
|
866
|
+
var isPropagationTraversalDirection2 = isPropagationTraversalDirection;
|
|
874
867
|
var EDGE_PROPAGATION_SPECS = [
|
|
875
868
|
supportsPropagationSpec,
|
|
876
869
|
informsPropagationSpec,
|
|
@@ -887,16 +880,15 @@ function getEdgePropagationSpecs() {
|
|
|
887
880
|
return EDGE_PROPAGATION_SPECS;
|
|
888
881
|
}
|
|
889
882
|
function getTraversalDirections(direction) {
|
|
890
|
-
if (
|
|
883
|
+
if (isPropagationTraversalDirection2(direction)) {
|
|
891
884
|
return [direction];
|
|
892
885
|
}
|
|
893
886
|
return ["outgoing", "incoming"];
|
|
894
887
|
}
|
|
895
888
|
|
|
896
889
|
// src/confidencePropagationDispatch.ts
|
|
897
|
-
function
|
|
898
|
-
|
|
899
|
-
return targetNodeId ?? void 0;
|
|
890
|
+
function nodeIdToCacheKey(nodeId) {
|
|
891
|
+
return String(nodeId);
|
|
900
892
|
}
|
|
901
893
|
function readNodeOpinion(node) {
|
|
902
894
|
const metadata = node.metadata ?? {};
|
|
@@ -912,118 +904,354 @@ function readNodeOpinion(node) {
|
|
|
912
904
|
return mkOpinion(0, 0, 1, 0.5);
|
|
913
905
|
}
|
|
914
906
|
}
|
|
907
|
+
function resolveTraversalTargetNodeId(edge, direction) {
|
|
908
|
+
const targetNodeId = direction === "outgoing" ? edge.toNodeId : edge.fromNodeId;
|
|
909
|
+
return targetNodeId ?? void 0;
|
|
910
|
+
}
|
|
911
|
+
function buildInitialState(sourceNodeId, sourceOpinion) {
|
|
912
|
+
return {
|
|
913
|
+
nodeId: sourceNodeId,
|
|
914
|
+
opinion: sourceOpinion,
|
|
915
|
+
hop: 0,
|
|
916
|
+
visitedNodeIds: /* @__PURE__ */ new Set([nodeIdToCacheKey(sourceNodeId)])
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
function extendVisited(currentVisited, targetNodeId) {
|
|
920
|
+
return /* @__PURE__ */ new Set([...currentVisited, nodeIdToCacheKey(targetNodeId)]);
|
|
921
|
+
}
|
|
922
|
+
function makeTransitiveState(current, targetNodeId, projectedOpinion, nextHop) {
|
|
923
|
+
return {
|
|
924
|
+
nodeId: targetNodeId,
|
|
925
|
+
opinion: projectedOpinion,
|
|
926
|
+
hop: nextHop,
|
|
927
|
+
visitedNodeIds: extendVisited(current.visitedNodeIds, targetNodeId)
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
function makeDispatchRecord(targetNodeId, spec, direction, edge, projectedOpinion, nextHop, result, existingDispatch) {
|
|
931
|
+
return {
|
|
932
|
+
targetNodeId,
|
|
933
|
+
edgeType: spec.edgeType,
|
|
934
|
+
traversedDirection: direction,
|
|
935
|
+
weight: edge.weight ?? 1,
|
|
936
|
+
opinion: projectedOpinion,
|
|
937
|
+
operator: result.operator,
|
|
938
|
+
rationale: existingDispatch ? `${existingDispatch.rationale}; ${result.rationale}` : result.rationale,
|
|
939
|
+
hop: nextHop
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
async function loadCachedNode(scope, nodeId) {
|
|
943
|
+
const cacheKey = nodeIdToCacheKey(nodeId);
|
|
944
|
+
if (!scope.nodeCache.has(cacheKey)) {
|
|
945
|
+
scope.nodeCache.set(cacheKey, await scope.args.getNode(nodeId));
|
|
946
|
+
}
|
|
947
|
+
return scope.nodeCache.get(cacheKey) ?? null;
|
|
948
|
+
}
|
|
949
|
+
async function collectTargetDispatch(state, nextHop, spec, direction, edge, queue, scope) {
|
|
950
|
+
const sourceScope = scope.args.sourceScope;
|
|
951
|
+
if (sourceScope && !edgeMatchesWorkspaceReasoningScope(edge, sourceScope)) {
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
const targetNodeId = resolveTraversalTargetNodeId(edge, direction);
|
|
955
|
+
if (!targetNodeId) {
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
const targetNodeIdKey = nodeIdToCacheKey(targetNodeId);
|
|
959
|
+
if (state.visitedNodeIds.has(targetNodeIdKey)) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
const targetNode = await loadCachedNode(scope, targetNodeId);
|
|
963
|
+
if (targetNode?.nodeType !== "belief") {
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
if (sourceScope && !nodeMatchesWorkspaceReasoningScope(targetNode, sourceScope)) {
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
const targetOpinion = scope.opinionCache.get(targetNodeIdKey) ?? readNodeOpinion(targetNode);
|
|
970
|
+
const result = spec.operator(state.opinion, targetOpinion, edge, {
|
|
971
|
+
hop: nextHop,
|
|
972
|
+
sourceNodeId: state.nodeId,
|
|
973
|
+
targetNodeId,
|
|
974
|
+
traversedDirection: direction,
|
|
975
|
+
spec
|
|
976
|
+
});
|
|
977
|
+
if (!(result && hasProjectedOpinionChanged(targetOpinion, result.opinion))) {
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
const projectedOpinion = mkOpinion(
|
|
981
|
+
result.opinion.b,
|
|
982
|
+
result.opinion.d,
|
|
983
|
+
result.opinion.u,
|
|
984
|
+
result.opinion.a
|
|
985
|
+
);
|
|
986
|
+
scope.opinionCache.set(targetNodeIdKey, projectedOpinion);
|
|
987
|
+
const existingDispatch = scope.dispatchesByTargetId.get(targetNodeIdKey);
|
|
988
|
+
scope.dispatchesByTargetId.set(
|
|
989
|
+
targetNodeIdKey,
|
|
990
|
+
makeDispatchRecord(
|
|
991
|
+
targetNodeId,
|
|
992
|
+
spec,
|
|
993
|
+
direction,
|
|
994
|
+
edge,
|
|
995
|
+
projectedOpinion,
|
|
996
|
+
nextHop,
|
|
997
|
+
result,
|
|
998
|
+
existingDispatch
|
|
999
|
+
)
|
|
1000
|
+
);
|
|
1001
|
+
if (canContinueTransitively2(spec, nextHop)) {
|
|
1002
|
+
queue.push(
|
|
1003
|
+
makeTransitiveState(state, targetNodeId, projectedOpinion, nextHop)
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
async function processTraversalSpec(state, nextHop, spec, queue, scope) {
|
|
1008
|
+
const sourceNodeId = state.nodeId;
|
|
1009
|
+
for (const direction of getTraversalDirections(spec.direction)) {
|
|
1010
|
+
const edges = await scope.args.queryEdges({
|
|
1011
|
+
nodeId: sourceNodeId,
|
|
1012
|
+
spec,
|
|
1013
|
+
direction,
|
|
1014
|
+
hop: nextHop
|
|
1015
|
+
});
|
|
1016
|
+
for (const edge of edges) {
|
|
1017
|
+
await collectTargetDispatch(
|
|
1018
|
+
state,
|
|
1019
|
+
nextHop,
|
|
1020
|
+
spec,
|
|
1021
|
+
direction,
|
|
1022
|
+
edge,
|
|
1023
|
+
queue,
|
|
1024
|
+
scope
|
|
1025
|
+
);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
async function processQueuedState(state, queue, scope) {
|
|
1030
|
+
const nextHop = state.hop + 1;
|
|
1031
|
+
for (const spec of scope.traversalSpecs) {
|
|
1032
|
+
if (!canTraverseHop2(spec, nextHop)) {
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
await processTraversalSpec(state, nextHop, spec, queue, scope);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
function sortDispatches(dispatches) {
|
|
1039
|
+
return Array.from(dispatches).sort((left, right) => {
|
|
1040
|
+
if (left.hop !== right.hop) {
|
|
1041
|
+
return left.hop - right.hop;
|
|
1042
|
+
}
|
|
1043
|
+
return String(left.targetNodeId).localeCompare(String(right.targetNodeId));
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
915
1046
|
async function collectConfidencePropagationDispatches(args) {
|
|
916
1047
|
const dispatchesByTargetId = /* @__PURE__ */ new Map();
|
|
917
1048
|
const opinionCache = /* @__PURE__ */ new Map();
|
|
918
1049
|
const nodeCache = /* @__PURE__ */ new Map();
|
|
919
1050
|
const traversalSpecs = args.traversalSpecs ?? getEdgePropagationSpecs();
|
|
1051
|
+
const scope = {
|
|
1052
|
+
args,
|
|
1053
|
+
dispatchesByTargetId,
|
|
1054
|
+
opinionCache,
|
|
1055
|
+
nodeCache,
|
|
1056
|
+
traversalSpecs
|
|
1057
|
+
};
|
|
920
1058
|
const queue = [
|
|
921
|
-
|
|
922
|
-
nodeId: args.sourceNodeId,
|
|
923
|
-
opinion: args.sourceOpinion,
|
|
924
|
-
hop: 0,
|
|
925
|
-
visitedNodeIds: /* @__PURE__ */ new Set([String(args.sourceNodeId)])
|
|
926
|
-
}
|
|
1059
|
+
buildInitialState(args.sourceNodeId, args.sourceOpinion)
|
|
927
1060
|
];
|
|
928
|
-
const loadNode = async (nodeId) => {
|
|
929
|
-
const cacheKey = String(nodeId);
|
|
930
|
-
if (!nodeCache.has(cacheKey)) {
|
|
931
|
-
nodeCache.set(cacheKey, await args.getNode(nodeId));
|
|
932
|
-
}
|
|
933
|
-
return nodeCache.get(cacheKey) ?? null;
|
|
934
|
-
};
|
|
935
1061
|
while (queue.length > 0) {
|
|
936
1062
|
const state = queue.shift();
|
|
937
1063
|
if (!state) {
|
|
938
1064
|
continue;
|
|
939
1065
|
}
|
|
940
|
-
|
|
941
|
-
const nextHop = state.hop + 1;
|
|
942
|
-
if (!canTraverseHop(spec, nextHop)) {
|
|
943
|
-
continue;
|
|
944
|
-
}
|
|
945
|
-
for (const direction of getTraversalDirections(spec.direction)) {
|
|
946
|
-
const edges = await args.queryEdges({
|
|
947
|
-
nodeId: state.nodeId,
|
|
948
|
-
spec,
|
|
949
|
-
direction,
|
|
950
|
-
hop: nextHop
|
|
951
|
-
});
|
|
952
|
-
for (const edge of edges) {
|
|
953
|
-
if (args.sourceScope && !edgeMatchesWorkspaceReasoningScope(edge, args.sourceScope)) {
|
|
954
|
-
continue;
|
|
955
|
-
}
|
|
956
|
-
const targetNodeId = resolveTraversalTargetNodeId(edge, direction);
|
|
957
|
-
if (!targetNodeId) {
|
|
958
|
-
continue;
|
|
959
|
-
}
|
|
960
|
-
if (state.visitedNodeIds.has(String(targetNodeId))) {
|
|
961
|
-
continue;
|
|
962
|
-
}
|
|
963
|
-
const targetNode = await loadNode(targetNodeId);
|
|
964
|
-
if (!targetNode || targetNode.nodeType !== "belief") {
|
|
965
|
-
continue;
|
|
966
|
-
}
|
|
967
|
-
if (args.sourceScope && !nodeMatchesWorkspaceReasoningScope(targetNode, args.sourceScope)) {
|
|
968
|
-
continue;
|
|
969
|
-
}
|
|
970
|
-
const cacheKey = String(targetNodeId);
|
|
971
|
-
const targetOpinion = opinionCache.get(cacheKey) ?? readNodeOpinion(targetNode);
|
|
972
|
-
const result = spec.operator(state.opinion, targetOpinion, edge, {
|
|
973
|
-
hop: nextHop,
|
|
974
|
-
sourceNodeId: state.nodeId,
|
|
975
|
-
targetNodeId,
|
|
976
|
-
traversedDirection: direction,
|
|
977
|
-
spec
|
|
978
|
-
});
|
|
979
|
-
if (!result || !hasProjectedOpinionChanged(targetOpinion, result.opinion)) {
|
|
980
|
-
continue;
|
|
981
|
-
}
|
|
982
|
-
const projectedOpinion = mkOpinion(
|
|
983
|
-
result.opinion.b,
|
|
984
|
-
result.opinion.d,
|
|
985
|
-
result.opinion.u,
|
|
986
|
-
result.opinion.a
|
|
987
|
-
);
|
|
988
|
-
opinionCache.set(cacheKey, projectedOpinion);
|
|
989
|
-
const existingDispatch = dispatchesByTargetId.get(cacheKey);
|
|
990
|
-
dispatchesByTargetId.set(cacheKey, {
|
|
991
|
-
targetNodeId,
|
|
992
|
-
edgeType: spec.edgeType,
|
|
993
|
-
traversedDirection: direction,
|
|
994
|
-
weight: edge.weight ?? 1,
|
|
995
|
-
opinion: projectedOpinion,
|
|
996
|
-
operator: result.operator,
|
|
997
|
-
rationale: existingDispatch ? `${existingDispatch.rationale}; ${result.rationale}` : result.rationale,
|
|
998
|
-
hop: nextHop
|
|
999
|
-
});
|
|
1000
|
-
if (canContinueTransitively(spec, nextHop)) {
|
|
1001
|
-
queue.push({
|
|
1002
|
-
nodeId: targetNodeId,
|
|
1003
|
-
opinion: projectedOpinion,
|
|
1004
|
-
hop: nextHop,
|
|
1005
|
-
visitedNodeIds: /* @__PURE__ */ new Set([
|
|
1006
|
-
...state.visitedNodeIds,
|
|
1007
|
-
String(targetNodeId)
|
|
1008
|
-
])
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1066
|
+
await processQueuedState(state, queue, scope);
|
|
1014
1067
|
}
|
|
1015
|
-
return
|
|
1016
|
-
if (left.hop !== right.hop) {
|
|
1017
|
-
return left.hop - right.hop;
|
|
1018
|
-
}
|
|
1019
|
-
return String(left.targetNodeId).localeCompare(String(right.targetNodeId));
|
|
1020
|
-
});
|
|
1068
|
+
return sortDispatches(dispatchesByTargetId.values());
|
|
1021
1069
|
}
|
|
1022
1070
|
|
|
1023
1071
|
// src/epistemicBeliefs.confidence.ts
|
|
1072
|
+
function isRecord(value) {
|
|
1073
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1074
|
+
}
|
|
1075
|
+
function readConvexId(value) {
|
|
1076
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1077
|
+
}
|
|
1078
|
+
function readOptionalBoolean(value) {
|
|
1079
|
+
return typeof value === "boolean" ? value : void 0;
|
|
1080
|
+
}
|
|
1081
|
+
function readOptionalNumber(value) {
|
|
1082
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1083
|
+
}
|
|
1084
|
+
function readOptionalString(value) {
|
|
1085
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1086
|
+
}
|
|
1087
|
+
function readRecord(value) {
|
|
1088
|
+
return isRecord(value) ? value : void 0;
|
|
1089
|
+
}
|
|
1090
|
+
function readConfidenceBeliefNode(value) {
|
|
1091
|
+
if (!isRecord(value)) {
|
|
1092
|
+
return null;
|
|
1093
|
+
}
|
|
1094
|
+
const id = readConvexId(value._id);
|
|
1095
|
+
const nodeType = readOptionalString(value.nodeType);
|
|
1096
|
+
const projectId = readOptionalString(value.projectId);
|
|
1097
|
+
if (!(id && nodeType === "belief" && projectId)) {
|
|
1098
|
+
return null;
|
|
1099
|
+
}
|
|
1100
|
+
const node = {
|
|
1101
|
+
_id: id,
|
|
1102
|
+
nodeType,
|
|
1103
|
+
projectId
|
|
1104
|
+
};
|
|
1105
|
+
const confidence = readOptionalNumber(value.confidence);
|
|
1106
|
+
const epistemicLayer = readOptionalString(value.epistemicLayer);
|
|
1107
|
+
const globalId = readOptionalString(value.globalId);
|
|
1108
|
+
const metadata = readRecord(value.metadata);
|
|
1109
|
+
const opinionA = readOptionalNumber(value.opinion_a);
|
|
1110
|
+
const opinionB = readOptionalNumber(value.opinion_b);
|
|
1111
|
+
const opinionD = readOptionalNumber(value.opinion_d);
|
|
1112
|
+
const opinionU = readOptionalNumber(value.opinion_u);
|
|
1113
|
+
const predictionMeta = readRecord(value.predictionMeta);
|
|
1114
|
+
const publicationStatus = readOptionalString(value.publicationStatus);
|
|
1115
|
+
const status = readOptionalString(value.status);
|
|
1116
|
+
const tenantId = readOptionalString(value.tenantId);
|
|
1117
|
+
const topicId = readOptionalString(value.topicId);
|
|
1118
|
+
const tupleContradicted = readOptionalBoolean(value.tupleContradicted);
|
|
1119
|
+
const workspaceId = readOptionalString(value.workspaceId);
|
|
1120
|
+
if (confidence !== void 0) {
|
|
1121
|
+
node.confidence = confidence;
|
|
1122
|
+
}
|
|
1123
|
+
if (epistemicLayer !== void 0) {
|
|
1124
|
+
node.epistemicLayer = epistemicLayer;
|
|
1125
|
+
}
|
|
1126
|
+
if (globalId !== void 0) {
|
|
1127
|
+
node.globalId = globalId;
|
|
1128
|
+
}
|
|
1129
|
+
if (metadata !== void 0) {
|
|
1130
|
+
node.metadata = metadata;
|
|
1131
|
+
}
|
|
1132
|
+
if (opinionA !== void 0) {
|
|
1133
|
+
node.opinion_a = opinionA;
|
|
1134
|
+
}
|
|
1135
|
+
if (opinionB !== void 0) {
|
|
1136
|
+
node.opinion_b = opinionB;
|
|
1137
|
+
}
|
|
1138
|
+
if (opinionD !== void 0) {
|
|
1139
|
+
node.opinion_d = opinionD;
|
|
1140
|
+
}
|
|
1141
|
+
if (opinionU !== void 0) {
|
|
1142
|
+
node.opinion_u = opinionU;
|
|
1143
|
+
}
|
|
1144
|
+
if (predictionMeta !== void 0) {
|
|
1145
|
+
node.predictionMeta = predictionMeta;
|
|
1146
|
+
}
|
|
1147
|
+
if (publicationStatus !== void 0) {
|
|
1148
|
+
node.publicationStatus = publicationStatus;
|
|
1149
|
+
}
|
|
1150
|
+
if (status !== void 0) {
|
|
1151
|
+
node.status = status;
|
|
1152
|
+
}
|
|
1153
|
+
if (tenantId !== void 0) {
|
|
1154
|
+
node.tenantId = tenantId;
|
|
1155
|
+
}
|
|
1156
|
+
if (topicId !== void 0) {
|
|
1157
|
+
node.topicId = topicId;
|
|
1158
|
+
}
|
|
1159
|
+
if (tupleContradicted !== void 0) {
|
|
1160
|
+
node.tupleContradicted = tupleContradicted;
|
|
1161
|
+
}
|
|
1162
|
+
if (workspaceId !== void 0) {
|
|
1163
|
+
node.workspaceId = workspaceId;
|
|
1164
|
+
}
|
|
1165
|
+
return node;
|
|
1166
|
+
}
|
|
1167
|
+
function readPropagationEdge(value) {
|
|
1168
|
+
if (!isRecord(value)) {
|
|
1169
|
+
return null;
|
|
1170
|
+
}
|
|
1171
|
+
const edgeType = readOptionalString(value.edgeType);
|
|
1172
|
+
if (!edgeType) {
|
|
1173
|
+
return null;
|
|
1174
|
+
}
|
|
1175
|
+
const edge = { edgeType };
|
|
1176
|
+
const fromNodeId = readConvexId(value.fromNodeId);
|
|
1177
|
+
const tenantId = readOptionalString(value.tenantId);
|
|
1178
|
+
const toNodeId = readConvexId(value.toNodeId);
|
|
1179
|
+
const weight = readOptionalNumber(value.weight);
|
|
1180
|
+
const workspaceId = readOptionalString(value.workspaceId);
|
|
1181
|
+
if (fromNodeId !== void 0) {
|
|
1182
|
+
edge.fromNodeId = fromNodeId;
|
|
1183
|
+
}
|
|
1184
|
+
if (tenantId !== void 0) {
|
|
1185
|
+
edge.tenantId = tenantId;
|
|
1186
|
+
}
|
|
1187
|
+
if (toNodeId !== void 0) {
|
|
1188
|
+
edge.toNodeId = toNodeId;
|
|
1189
|
+
}
|
|
1190
|
+
if (weight !== void 0) {
|
|
1191
|
+
edge.weight = weight;
|
|
1192
|
+
}
|
|
1193
|
+
if (workspaceId !== void 0) {
|
|
1194
|
+
edge.workspaceId = workspaceId;
|
|
1195
|
+
}
|
|
1196
|
+
return edge;
|
|
1197
|
+
}
|
|
1198
|
+
function readRowList(values, reader) {
|
|
1199
|
+
return values.flatMap((value) => {
|
|
1200
|
+
const row = reader(value);
|
|
1201
|
+
return row ? [row] : [];
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1024
1204
|
async function applyBeliefConfidenceChange(ctx, args) {
|
|
1025
1205
|
const now = Date.now();
|
|
1026
|
-
const node = await ctx
|
|
1206
|
+
const node = await requireConfidenceBeliefNode(ctx, args);
|
|
1207
|
+
const state = await buildConfidenceChangeState(ctx, node, args);
|
|
1208
|
+
await assertConfidenceScoringPolicySatisfied(ctx, args, state);
|
|
1209
|
+
const tupleContradictionId = await createTupleContradictionIfNeeded(
|
|
1210
|
+
ctx,
|
|
1211
|
+
args,
|
|
1212
|
+
node,
|
|
1213
|
+
state
|
|
1214
|
+
);
|
|
1215
|
+
await patchBeliefConfidenceState(ctx, args, state);
|
|
1216
|
+
await scheduleFirstScoringThemeEdges(ctx, args, node, state);
|
|
1217
|
+
const beliefConfidenceId = await insertBeliefConfidenceRecord(
|
|
1218
|
+
ctx,
|
|
1219
|
+
args,
|
|
1220
|
+
state,
|
|
1221
|
+
tupleContradictionId,
|
|
1222
|
+
now
|
|
1223
|
+
);
|
|
1224
|
+
await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
|
|
1225
|
+
nodeId: args.nodeId,
|
|
1226
|
+
operation: "upsert"
|
|
1227
|
+
});
|
|
1228
|
+
await insertConfidenceAudit(
|
|
1229
|
+
ctx,
|
|
1230
|
+
args,
|
|
1231
|
+
node,
|
|
1232
|
+
state,
|
|
1233
|
+
tupleContradictionId,
|
|
1234
|
+
now
|
|
1235
|
+
);
|
|
1236
|
+
await insertTupleTransitionAuditIfNeeded(
|
|
1237
|
+
ctx,
|
|
1238
|
+
args,
|
|
1239
|
+
node,
|
|
1240
|
+
state,
|
|
1241
|
+
tupleContradictionId,
|
|
1242
|
+
now
|
|
1243
|
+
);
|
|
1244
|
+
await scheduleConfidenceFollowups(ctx, args, node, state);
|
|
1245
|
+
return {
|
|
1246
|
+
nodeId: args.nodeId,
|
|
1247
|
+
previousConfidence: state.previousConfidence,
|
|
1248
|
+
newConfidence: state.derivedConfidence,
|
|
1249
|
+
opinion: state.nextOpinion,
|
|
1250
|
+
beliefConfidenceId
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
async function requireConfidenceBeliefNode(ctx, args) {
|
|
1254
|
+
const node = readConfidenceBeliefNode(await ctx.db.get(args.nodeId));
|
|
1027
1255
|
if (!node) {
|
|
1028
1256
|
throwStructuredMutationError({
|
|
1029
1257
|
message: "Node not found.",
|
|
@@ -1034,59 +1262,28 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1034
1262
|
details: { nodeId: args.nodeId }
|
|
1035
1263
|
});
|
|
1036
1264
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
invariantCode: "entity.no_confidence",
|
|
1043
|
-
suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. appendSlScoring is for belief nodes only.",
|
|
1044
|
-
details: { nodeId: args.nodeId, nodeType: node.nodeType }
|
|
1045
|
-
});
|
|
1046
|
-
}
|
|
1047
|
-
if (!node.projectId) {
|
|
1048
|
-
throwStructuredMutationError({
|
|
1049
|
-
message: "Belief has no project scope.",
|
|
1050
|
-
status: 400,
|
|
1051
|
-
code: "MISSING_SCOPE",
|
|
1052
|
-
invariantCode: "belief.project_required",
|
|
1053
|
-
suggestion: "Belief must have a projectId before SL scoring can be appended.",
|
|
1054
|
-
details: { nodeId: args.nodeId }
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
await requireScopeWriteAccess(
|
|
1058
|
-
ctx,
|
|
1059
|
-
node.projectId,
|
|
1060
|
-
args.authenticatedUserId
|
|
1061
|
-
);
|
|
1062
|
-
const existingMetadata = node.metadata || {};
|
|
1265
|
+
await requireScopeWriteAccess(ctx, node.projectId, args.authenticatedUserId);
|
|
1266
|
+
return node;
|
|
1267
|
+
}
|
|
1268
|
+
async function buildConfidenceChangeState(ctx, node, args) {
|
|
1269
|
+
const existingMetadata = readNodeMetadata(node);
|
|
1063
1270
|
const currentBeliefStatus = resolveBeliefStatus(node, existingMetadata);
|
|
1064
1271
|
const confidencePolicy = await getActiveConfidencePolicy(ctx);
|
|
1065
|
-
if (confidencePolicy.scoringMode === "after_worktree" && isPreValidationBeliefStatus(currentBeliefStatus)) {
|
|
1066
|
-
const hasCompletedWorktree = await hasCompletedWorktreeForBelief(
|
|
1067
|
-
ctx,
|
|
1068
|
-
args.nodeId
|
|
1069
|
-
);
|
|
1070
|
-
if (!hasCompletedWorktree) {
|
|
1071
|
-
throwStructuredMutationError({
|
|
1072
|
-
message: "Cannot score belief before worktree completion. Complete a worktree that tests this belief first.",
|
|
1073
|
-
status: 409,
|
|
1074
|
-
code: "CONFLICT",
|
|
1075
|
-
invariantCode: "belief.confidence_append_only",
|
|
1076
|
-
suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
|
|
1077
|
-
details: { nodeId: args.nodeId }
|
|
1078
|
-
});
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
1272
|
const previousConfidence = node.confidence || 0.5;
|
|
1082
1273
|
const predictionMeta = node.predictionMeta || existingMetadata.predictionMeta;
|
|
1083
1274
|
const previousOpinion = readBeliefOpinionSnapshot(node, existingMetadata);
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1275
|
+
const nextOpinion = {
|
|
1276
|
+
b: args.belief,
|
|
1277
|
+
d: args.disbelief,
|
|
1278
|
+
u: args.uncertainty,
|
|
1279
|
+
a: args.baseRate ?? 0.5
|
|
1280
|
+
};
|
|
1281
|
+
const derivedConfidence = confidenceFromSL(
|
|
1282
|
+
nextOpinion.b,
|
|
1283
|
+
nextOpinion.d,
|
|
1284
|
+
nextOpinion.u,
|
|
1285
|
+
nextOpinion.a
|
|
1286
|
+
);
|
|
1090
1287
|
const isFirstScoring = typeof node.confidence !== "number" || !Number.isFinite(node.confidence);
|
|
1091
1288
|
const previousTupleContradicted = readTupleContradictedFlag(node.tupleContradicted) ?? readTupleContradictedFlag(existingMetadata.tupleContradicted) ?? detectTupleContradiction(
|
|
1092
1289
|
previousOpinion,
|
|
@@ -1107,79 +1304,121 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1107
1304
|
predictionMeta,
|
|
1108
1305
|
metadata: existingMetadata
|
|
1109
1306
|
});
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1307
|
+
const storedRationale = args.rationale ?? `Confidence changed from ${previousConfidence.toFixed(2)} (nodeId: ${args.nodeId})`;
|
|
1308
|
+
return {
|
|
1309
|
+
confidencePolicy,
|
|
1310
|
+
currentBeliefStatus,
|
|
1311
|
+
derivedConfidence,
|
|
1312
|
+
existingMetadata,
|
|
1313
|
+
isFirstScoring,
|
|
1314
|
+
newBeliefStatus,
|
|
1315
|
+
nextOpinion,
|
|
1316
|
+
previousConfidence,
|
|
1317
|
+
previousTupleContradicted,
|
|
1318
|
+
storedRationale,
|
|
1319
|
+
tupleContradictionDescription,
|
|
1320
|
+
tupleTransition
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
function readNodeMetadata(node) {
|
|
1324
|
+
return node.metadata ?? {};
|
|
1325
|
+
}
|
|
1326
|
+
async function assertConfidenceScoringPolicySatisfied(ctx, args, state) {
|
|
1327
|
+
if (state.confidencePolicy.scoringMode !== "after_worktree" || !isPreValidationBeliefStatus(state.currentBeliefStatus)) {
|
|
1328
|
+
return;
|
|
1329
|
+
}
|
|
1330
|
+
const hasCompletedWorktree = await hasCompletedWorktreeForBelief(
|
|
1331
|
+
ctx,
|
|
1332
|
+
args.nodeId
|
|
1333
|
+
);
|
|
1334
|
+
if (hasCompletedWorktree) {
|
|
1335
|
+
return;
|
|
1128
1336
|
}
|
|
1337
|
+
throwStructuredMutationError({
|
|
1338
|
+
message: "Cannot score belief before worktree completion. Complete a worktree that tests this belief first.",
|
|
1339
|
+
status: 409,
|
|
1340
|
+
code: "CONFLICT",
|
|
1341
|
+
invariantCode: "belief.confidence_append_only",
|
|
1342
|
+
suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
|
|
1343
|
+
details: { nodeId: args.nodeId }
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
async function createTupleContradictionIfNeeded(ctx, args, node, state) {
|
|
1347
|
+
if (!state.tupleTransition.crossedIntoTupleContradiction) {
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
return await ctx.runMutation("contradictions:create", {
|
|
1351
|
+
projectId: node.projectId,
|
|
1352
|
+
topicId: node.topicId,
|
|
1353
|
+
beliefId: args.nodeId,
|
|
1354
|
+
beliefBId: args.nodeId,
|
|
1355
|
+
supportingInsightIds: [],
|
|
1356
|
+
contradictingInsightIds: [],
|
|
1357
|
+
severity: deriveTupleContradictionSeverity(node),
|
|
1358
|
+
source: "tuple_space",
|
|
1359
|
+
detectionMethod: "agent",
|
|
1360
|
+
description: state.tupleContradictionDescription,
|
|
1361
|
+
createdBy: args.authenticatedUserId
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
async function patchBeliefConfidenceState(ctx, args, state) {
|
|
1129
1365
|
await ctx.db.patch(args.nodeId, {
|
|
1130
|
-
confidence: derivedConfidence,
|
|
1131
|
-
beliefStatus: newBeliefStatus,
|
|
1132
|
-
tupleContradicted: tupleTransition.tupleContradicted,
|
|
1133
|
-
updatedAt: now,
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
opinion_a: slA,
|
|
1366
|
+
confidence: state.derivedConfidence,
|
|
1367
|
+
beliefStatus: state.newBeliefStatus,
|
|
1368
|
+
tupleContradicted: state.tupleTransition.tupleContradicted,
|
|
1369
|
+
updatedAt: Date.now(),
|
|
1370
|
+
opinion_b: state.nextOpinion.b,
|
|
1371
|
+
opinion_d: state.nextOpinion.d,
|
|
1372
|
+
opinion_u: state.nextOpinion.u,
|
|
1373
|
+
opinion_a: state.nextOpinion.a,
|
|
1139
1374
|
metadata: {
|
|
1140
|
-
...existingMetadata,
|
|
1141
|
-
beliefStatus: newBeliefStatus,
|
|
1142
|
-
slBelief:
|
|
1143
|
-
slDisbelief:
|
|
1144
|
-
slUncertainty:
|
|
1145
|
-
slBaseRate:
|
|
1146
|
-
tupleContradicted: tupleTransition.tupleContradicted
|
|
1375
|
+
...state.existingMetadata,
|
|
1376
|
+
beliefStatus: state.newBeliefStatus,
|
|
1377
|
+
slBelief: state.nextOpinion.b,
|
|
1378
|
+
slDisbelief: state.nextOpinion.d,
|
|
1379
|
+
slUncertainty: state.nextOpinion.u,
|
|
1380
|
+
slBaseRate: state.nextOpinion.a,
|
|
1381
|
+
tupleContradicted: state.tupleTransition.tupleContradicted
|
|
1147
1382
|
}
|
|
1148
1383
|
});
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
edgeType: "relates_to_thesis",
|
|
1162
|
-
weight: derivedConfidence,
|
|
1163
|
-
createdBy: args.authenticatedUserId,
|
|
1164
|
-
topicId: String(node.projectId),
|
|
1165
|
-
fromNodeType: "belief",
|
|
1166
|
-
toNodeType: "theme",
|
|
1167
|
-
fromLayer: "L3",
|
|
1168
|
-
toLayer: "L3"
|
|
1169
|
-
});
|
|
1170
|
-
}
|
|
1384
|
+
}
|
|
1385
|
+
async function scheduleFirstScoringThemeEdges(ctx, args, node, state) {
|
|
1386
|
+
if (!state.isFirstScoring) {
|
|
1387
|
+
return;
|
|
1388
|
+
}
|
|
1389
|
+
const themeNodes = await ctx.db.query("epistemicNodes").withIndex(
|
|
1390
|
+
"by_topic",
|
|
1391
|
+
(q) => q.eq("topicId", node.topicId || node.projectId)
|
|
1392
|
+
).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
|
|
1393
|
+
for (const theme of themeNodes) {
|
|
1394
|
+
if (!(theme.globalId && node.globalId)) {
|
|
1395
|
+
continue;
|
|
1171
1396
|
}
|
|
1397
|
+
await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
|
|
1398
|
+
globalId: `edge-${node.globalId}-relates_to_thesis-${theme.globalId}`,
|
|
1399
|
+
fromGlobalId: node.globalId,
|
|
1400
|
+
toGlobalId: theme.globalId,
|
|
1401
|
+
edgeType: "relates_to_thesis",
|
|
1402
|
+
weight: state.derivedConfidence,
|
|
1403
|
+
createdBy: args.authenticatedUserId,
|
|
1404
|
+
topicId: String(node.projectId),
|
|
1405
|
+
fromNodeType: "belief",
|
|
1406
|
+
toNodeType: "theme",
|
|
1407
|
+
fromLayer: "L3",
|
|
1408
|
+
toLayer: "L3"
|
|
1409
|
+
});
|
|
1172
1410
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1411
|
+
}
|
|
1412
|
+
async function insertBeliefConfidenceRecord(ctx, args, state, tupleContradictionId, now) {
|
|
1413
|
+
return await ctx.db.insert("beliefConfidence", {
|
|
1175
1414
|
...buildBeliefConfidenceRow({
|
|
1176
1415
|
beliefId: args.nodeId,
|
|
1177
|
-
belief:
|
|
1178
|
-
disbelief:
|
|
1179
|
-
uncertainty:
|
|
1180
|
-
baseRate:
|
|
1416
|
+
belief: state.nextOpinion.b,
|
|
1417
|
+
disbelief: state.nextOpinion.d,
|
|
1418
|
+
uncertainty: state.nextOpinion.u,
|
|
1419
|
+
baseRate: state.nextOpinion.a,
|
|
1181
1420
|
trigger: args.trigger,
|
|
1182
|
-
rationale: storedRationale,
|
|
1421
|
+
rationale: state.storedRationale,
|
|
1183
1422
|
assessedBy: args.authenticatedUserId,
|
|
1184
1423
|
assessedAt: now,
|
|
1185
1424
|
slOperator: args.slOperator,
|
|
@@ -1188,25 +1427,23 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1188
1427
|
triggeringWorktreeId: args.triggeringWorktreeId
|
|
1189
1428
|
})
|
|
1190
1429
|
});
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
operation: "upsert"
|
|
1194
|
-
});
|
|
1430
|
+
}
|
|
1431
|
+
async function insertConfidenceAudit(ctx, args, node, state, tupleContradictionId, now) {
|
|
1195
1432
|
await ctx.db.insert("epistemicAudit", {
|
|
1196
1433
|
entityType: "belief",
|
|
1197
1434
|
entityId: args.nodeId,
|
|
1198
1435
|
changeType: "confidence_changed",
|
|
1199
1436
|
previousState: {
|
|
1200
|
-
confidence: previousConfidence,
|
|
1201
|
-
tupleContradicted: previousTupleContradicted
|
|
1437
|
+
confidence: state.previousConfidence,
|
|
1438
|
+
tupleContradicted: state.previousTupleContradicted
|
|
1202
1439
|
},
|
|
1203
1440
|
newState: {
|
|
1204
|
-
opinion: nextOpinion,
|
|
1205
|
-
confidence: derivedConfidence,
|
|
1441
|
+
opinion: state.nextOpinion,
|
|
1442
|
+
confidence: state.derivedConfidence,
|
|
1206
1443
|
trigger: args.trigger,
|
|
1207
|
-
rationale: storedRationale,
|
|
1208
|
-
tupleContradicted: tupleTransition.tupleContradicted,
|
|
1209
|
-
tupleContradictionPolicy: tupleTransition.policy,
|
|
1444
|
+
rationale: state.storedRationale,
|
|
1445
|
+
tupleContradicted: state.tupleTransition.tupleContradicted,
|
|
1446
|
+
tupleContradictionPolicy: state.tupleTransition.policy,
|
|
1210
1447
|
...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
|
|
1211
1448
|
},
|
|
1212
1449
|
changedBy: args.authenticatedUserId,
|
|
@@ -1215,28 +1452,39 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1215
1452
|
projectId: node.projectId,
|
|
1216
1453
|
topicId: node.topicId
|
|
1217
1454
|
});
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1455
|
+
}
|
|
1456
|
+
async function insertTupleTransitionAuditIfNeeded(ctx, args, node, state, tupleContradictionId, now) {
|
|
1457
|
+
if (!(state.tupleTransition.crossedIntoTupleContradiction || state.tupleTransition.crossedOutOfTupleContradiction)) {
|
|
1458
|
+
return;
|
|
1459
|
+
}
|
|
1460
|
+
await ctx.db.insert("epistemicAudit", {
|
|
1461
|
+
entityType: "belief",
|
|
1462
|
+
entityId: args.nodeId,
|
|
1463
|
+
changeType: "updated",
|
|
1464
|
+
previousState: { tupleContradicted: state.previousTupleContradicted },
|
|
1465
|
+
newState: {
|
|
1466
|
+
tupleContradicted: state.tupleTransition.tupleContradicted,
|
|
1467
|
+
action: state.tupleTransition.crossedIntoTupleContradiction ? "tuple_contradiction_detected" : "tuple_contradiction_cleared",
|
|
1468
|
+
opinion: state.nextOpinion,
|
|
1469
|
+
tupleContradictionPolicy: state.tupleTransition.policy,
|
|
1470
|
+
...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
|
|
1471
|
+
},
|
|
1472
|
+
rationale: tupleAuditRationale(state),
|
|
1473
|
+
changedBy: args.authenticatedUserId,
|
|
1474
|
+
isAgent: false,
|
|
1475
|
+
changedAt: now,
|
|
1476
|
+
projectId: node.projectId,
|
|
1477
|
+
topicId: node.topicId
|
|
1478
|
+
});
|
|
1479
|
+
}
|
|
1480
|
+
function tupleAuditRationale(state) {
|
|
1481
|
+
if (state.tupleTransition.crossedIntoTupleContradiction) {
|
|
1482
|
+
return state.tupleContradictionDescription;
|
|
1238
1483
|
}
|
|
1239
|
-
|
|
1484
|
+
return `Tuple-space contradiction cleared: b=${state.nextOpinion.b.toFixed(2)}, d=${state.nextOpinion.d.toFixed(2)} no longer exceed the configured policy thresholds.`;
|
|
1485
|
+
}
|
|
1486
|
+
async function scheduleConfidenceFollowups(ctx, args, node, state) {
|
|
1487
|
+
if (Math.abs(state.derivedConfidence - state.previousConfidence) >= 0.15) {
|
|
1240
1488
|
await ctx.scheduler.runAfter(
|
|
1241
1489
|
5e3,
|
|
1242
1490
|
internal.bi.contradictionSemanticDetector.scanAffectedBeliefs,
|
|
@@ -1253,13 +1501,6 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1253
1501
|
{ nodeId: args.nodeId }
|
|
1254
1502
|
);
|
|
1255
1503
|
}
|
|
1256
|
-
return {
|
|
1257
|
-
nodeId: args.nodeId,
|
|
1258
|
-
previousConfidence,
|
|
1259
|
-
newConfidence: derivedConfidence,
|
|
1260
|
-
opinion: { b: slB, d: slD, u: slU, a: slA },
|
|
1261
|
-
beliefConfidenceId
|
|
1262
|
-
};
|
|
1263
1504
|
}
|
|
1264
1505
|
function propagationPressureLabel(edgeType, weight) {
|
|
1265
1506
|
if (edgeType === "contradicts" || edgeType === "refutes") {
|
|
@@ -1287,7 +1528,7 @@ internalMutation({
|
|
|
1287
1528
|
args.opinion_u,
|
|
1288
1529
|
args.opinion_a
|
|
1289
1530
|
);
|
|
1290
|
-
const sourceNode = await ctx.db.get(args.nodeId);
|
|
1531
|
+
const sourceNode = readConfidenceBeliefNode(await ctx.db.get(args.nodeId));
|
|
1291
1532
|
const sourceScope = await resolveNodeScopeForWorkspaceIsolation(
|
|
1292
1533
|
ctx,
|
|
1293
1534
|
sourceNode
|
|
@@ -1296,16 +1537,20 @@ internalMutation({
|
|
|
1296
1537
|
sourceNodeId: args.nodeId,
|
|
1297
1538
|
sourceOpinion,
|
|
1298
1539
|
sourceScope,
|
|
1299
|
-
queryEdges: async ({ nodeId, spec, direction }) =>
|
|
1300
|
-
|
|
1540
|
+
queryEdges: async ({ nodeId, spec, direction }) => readRowList(
|
|
1541
|
+
await ctx.db.query("epistemicEdges").withIndex(
|
|
1301
1542
|
direction === "outgoing" ? "by_from_type" : "by_to_type",
|
|
1302
1543
|
(q) => direction === "outgoing" ? q.eq("fromNodeId", nodeId).eq("edgeType", spec.edgeType) : q.eq("toNodeId", nodeId).eq("edgeType", spec.edgeType)
|
|
1303
|
-
).collect()
|
|
1304
|
-
|
|
1305
|
-
|
|
1544
|
+
).collect(),
|
|
1545
|
+
readPropagationEdge
|
|
1546
|
+
),
|
|
1547
|
+
getNode: async (nodeId) => readConfidenceBeliefNode(await ctx.db.get(nodeId))
|
|
1306
1548
|
});
|
|
1307
1549
|
for (const dispatch of dispatches) {
|
|
1308
|
-
const pressureLabel = propagationPressureLabel(
|
|
1550
|
+
const pressureLabel = propagationPressureLabel(
|
|
1551
|
+
dispatch.edgeType,
|
|
1552
|
+
dispatch.weight
|
|
1553
|
+
);
|
|
1309
1554
|
await applyBeliefConfidenceChange(ctx, {
|
|
1310
1555
|
nodeId: dispatch.targetNodeId,
|
|
1311
1556
|
belief: dispatch.opinion.b,
|
|
@@ -1335,9 +1580,7 @@ var ACTIVE_CONTRADICTION_STATUSES = /* @__PURE__ */ new Set([
|
|
|
1335
1580
|
"investigating",
|
|
1336
1581
|
"accepted_as_permanent"
|
|
1337
1582
|
]);
|
|
1338
|
-
var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
1339
|
-
"depends_on"
|
|
1340
|
-
]);
|
|
1583
|
+
var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set(["depends_on"]);
|
|
1341
1584
|
function classifyContradictionStatus(status) {
|
|
1342
1585
|
if (typeof status !== "string") {
|
|
1343
1586
|
return "active";
|
|
@@ -1350,6 +1593,99 @@ function classifyContradictionStatus(status) {
|
|
|
1350
1593
|
}
|
|
1351
1594
|
return "resolved";
|
|
1352
1595
|
}
|
|
1596
|
+
function isRecord2(value) {
|
|
1597
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1598
|
+
}
|
|
1599
|
+
function readOptionalNumber2(value) {
|
|
1600
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1601
|
+
}
|
|
1602
|
+
function readOptionalString2(value) {
|
|
1603
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1604
|
+
}
|
|
1605
|
+
function readConvexId2(value) {
|
|
1606
|
+
const normalized = readOptionalString2(value);
|
|
1607
|
+
return normalized;
|
|
1608
|
+
}
|
|
1609
|
+
function readMetricNodeDoc(value) {
|
|
1610
|
+
if (!isRecord2(value)) {
|
|
1611
|
+
return null;
|
|
1612
|
+
}
|
|
1613
|
+
const id = readConvexId2(value._id);
|
|
1614
|
+
const nodeType = readOptionalString2(value.nodeType);
|
|
1615
|
+
if (!(id && nodeType)) {
|
|
1616
|
+
return null;
|
|
1617
|
+
}
|
|
1618
|
+
const node = { _id: id, nodeType };
|
|
1619
|
+
const globalId = readOptionalString2(value.globalId);
|
|
1620
|
+
if (globalId !== void 0) {
|
|
1621
|
+
node.globalId = globalId;
|
|
1622
|
+
}
|
|
1623
|
+
if ("metadata" in value) {
|
|
1624
|
+
node.metadata = value.metadata;
|
|
1625
|
+
}
|
|
1626
|
+
const status = readOptionalString2(value.status);
|
|
1627
|
+
if (status !== void 0) {
|
|
1628
|
+
node.status = status;
|
|
1629
|
+
}
|
|
1630
|
+
return node;
|
|
1631
|
+
}
|
|
1632
|
+
function readIncomingEdgeRow(value) {
|
|
1633
|
+
if (!isRecord2(value)) {
|
|
1634
|
+
return null;
|
|
1635
|
+
}
|
|
1636
|
+
const fromNodeId = readOptionalString2(value.fromNodeId);
|
|
1637
|
+
if (!fromNodeId) {
|
|
1638
|
+
return null;
|
|
1639
|
+
}
|
|
1640
|
+
const edge = { fromNodeId };
|
|
1641
|
+
const id = readConvexId2(value._id);
|
|
1642
|
+
if (id !== void 0) {
|
|
1643
|
+
edge._id = id;
|
|
1644
|
+
}
|
|
1645
|
+
const edgeType = readOptionalString2(value.edgeType);
|
|
1646
|
+
if (edgeType !== void 0) {
|
|
1647
|
+
edge.edgeType = edgeType;
|
|
1648
|
+
}
|
|
1649
|
+
const fromGlobalId = readOptionalString2(value.fromGlobalId);
|
|
1650
|
+
if (fromGlobalId !== void 0) {
|
|
1651
|
+
edge.fromGlobalId = fromGlobalId;
|
|
1652
|
+
}
|
|
1653
|
+
const fromUuid = readOptionalString2(value.fromUuid);
|
|
1654
|
+
if (fromUuid !== void 0) {
|
|
1655
|
+
edge.fromUuid = fromUuid;
|
|
1656
|
+
}
|
|
1657
|
+
const sourceGlobalId = readOptionalString2(value.sourceGlobalId);
|
|
1658
|
+
if (sourceGlobalId !== void 0) {
|
|
1659
|
+
edge.sourceGlobalId = sourceGlobalId;
|
|
1660
|
+
}
|
|
1661
|
+
const targetGlobalId = readOptionalString2(value.targetGlobalId);
|
|
1662
|
+
if (targetGlobalId !== void 0) {
|
|
1663
|
+
edge.targetGlobalId = targetGlobalId;
|
|
1664
|
+
}
|
|
1665
|
+
const toGlobalId = readOptionalString2(value.toGlobalId);
|
|
1666
|
+
if (toGlobalId !== void 0) {
|
|
1667
|
+
edge.toGlobalId = toGlobalId;
|
|
1668
|
+
}
|
|
1669
|
+
const toNodeId = readOptionalString2(value.toNodeId);
|
|
1670
|
+
if (toNodeId !== void 0) {
|
|
1671
|
+
edge.toNodeId = toNodeId;
|
|
1672
|
+
}
|
|
1673
|
+
const toUuid = readOptionalString2(value.toUuid);
|
|
1674
|
+
if (toUuid !== void 0) {
|
|
1675
|
+
edge.toUuid = toUuid;
|
|
1676
|
+
}
|
|
1677
|
+
const weight = readOptionalNumber2(value.weight);
|
|
1678
|
+
if (weight !== void 0) {
|
|
1679
|
+
edge.weight = weight;
|
|
1680
|
+
}
|
|
1681
|
+
for (const timestampField of ["_creationTime", "createdAt", "updatedAt"]) {
|
|
1682
|
+
const timestamp = readOptionalNumber2(value[timestampField]);
|
|
1683
|
+
if (timestamp !== void 0) {
|
|
1684
|
+
edge[timestampField] = timestamp;
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
return edge;
|
|
1688
|
+
}
|
|
1353
1689
|
function getEdgeTimestamp(edge) {
|
|
1354
1690
|
if (typeof edge.updatedAt === "number") {
|
|
1355
1691
|
return edge.updatedAt;
|
|
@@ -1362,22 +1698,86 @@ function getEdgeTimestamp(edge) {
|
|
|
1362
1698
|
}
|
|
1363
1699
|
return null;
|
|
1364
1700
|
}
|
|
1701
|
+
async function collectNodeEndpointRefs(ctx, nodeId) {
|
|
1702
|
+
const refs = /* @__PURE__ */ new Set([String(nodeId)]);
|
|
1703
|
+
const node = readMetricNodeDoc(await ctx.db.get(nodeId));
|
|
1704
|
+
if (node?.globalId) {
|
|
1705
|
+
refs.add(node.globalId);
|
|
1706
|
+
}
|
|
1707
|
+
return [...refs];
|
|
1708
|
+
}
|
|
1709
|
+
async function collectIncomingEdgeRows(ctx, nodeId, edgeType) {
|
|
1710
|
+
const refs = await collectNodeEndpointRefs(ctx, nodeId);
|
|
1711
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1712
|
+
const edges = [];
|
|
1713
|
+
for (const ref of refs) {
|
|
1714
|
+
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(
|
|
1715
|
+
"by_to_type",
|
|
1716
|
+
(q) => q.eq("toNodeId", ref).eq("edgeType", edgeType)
|
|
1717
|
+
).collect();
|
|
1718
|
+
for (const row of rows) {
|
|
1719
|
+
const edge = readIncomingEdgeRow(row);
|
|
1720
|
+
if (!edge) {
|
|
1721
|
+
continue;
|
|
1722
|
+
}
|
|
1723
|
+
if (edgeType !== void 0 && edge.edgeType !== edgeType) {
|
|
1724
|
+
continue;
|
|
1725
|
+
}
|
|
1726
|
+
const key = edge._id === void 0 ? `${edge.fromNodeId}->${edge.toNodeId ?? ref}:${edge.edgeType ?? ""}` : String(edge._id);
|
|
1727
|
+
if (seen.has(key)) {
|
|
1728
|
+
continue;
|
|
1729
|
+
}
|
|
1730
|
+
seen.add(key);
|
|
1731
|
+
edges.push(edge);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
return edges;
|
|
1735
|
+
}
|
|
1736
|
+
function sourceEndpointRefs(edge) {
|
|
1737
|
+
return [
|
|
1738
|
+
edge.fromNodeId,
|
|
1739
|
+
edge.sourceGlobalId,
|
|
1740
|
+
edge.fromGlobalId,
|
|
1741
|
+
edge.fromUuid
|
|
1742
|
+
].filter((value) => value !== void 0);
|
|
1743
|
+
}
|
|
1744
|
+
async function resolveEndpointNode(ctx, refs) {
|
|
1745
|
+
const candidates = refs.map((value) => value.trim()).filter(
|
|
1746
|
+
(value, index, values) => value.length > 0 && values.indexOf(value) === index
|
|
1747
|
+
);
|
|
1748
|
+
for (const candidate of candidates) {
|
|
1749
|
+
try {
|
|
1750
|
+
const direct = readMetricNodeDoc(
|
|
1751
|
+
await ctx.db.get(candidate)
|
|
1752
|
+
);
|
|
1753
|
+
if (direct) {
|
|
1754
|
+
return direct;
|
|
1755
|
+
}
|
|
1756
|
+
} catch {
|
|
1757
|
+
}
|
|
1758
|
+
const byGlobalId = readMetricNodeDoc(
|
|
1759
|
+
await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", candidate)).first()
|
|
1760
|
+
);
|
|
1761
|
+
if (byGlobalId) {
|
|
1762
|
+
return byGlobalId;
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
return null;
|
|
1766
|
+
}
|
|
1365
1767
|
async function getEvidenceLinks(ctx, beliefNodeId) {
|
|
1366
|
-
const edges = await ctx
|
|
1367
|
-
"by_to_type",
|
|
1368
|
-
(q) => q.eq("toNodeId", beliefNodeId).eq("edgeType", "informs")
|
|
1369
|
-
).collect();
|
|
1768
|
+
const edges = await collectIncomingEdgeRows(ctx, beliefNodeId, "informs");
|
|
1370
1769
|
if (edges.length === 0) {
|
|
1371
1770
|
return [];
|
|
1372
1771
|
}
|
|
1373
|
-
const
|
|
1374
|
-
|
|
1375
|
-
const node =
|
|
1376
|
-
if (
|
|
1377
|
-
|
|
1772
|
+
const links = [];
|
|
1773
|
+
for (const edge of edges) {
|
|
1774
|
+
const node = await resolveEndpointNode(ctx, sourceEndpointRefs(edge));
|
|
1775
|
+
if (node?.nodeType !== "evidence" || node.status === "archived") {
|
|
1776
|
+
continue;
|
|
1378
1777
|
}
|
|
1379
|
-
|
|
1380
|
-
}
|
|
1778
|
+
links.push({ edge, node });
|
|
1779
|
+
}
|
|
1780
|
+
return links;
|
|
1381
1781
|
}
|
|
1382
1782
|
function getEvidenceTags(node) {
|
|
1383
1783
|
const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : null;
|
|
@@ -1403,7 +1803,8 @@ async function computeTaggedEvidenceCount(args) {
|
|
|
1403
1803
|
};
|
|
1404
1804
|
}
|
|
1405
1805
|
async function computeContradictionCounts(ctx, beliefNodeId) {
|
|
1406
|
-
const
|
|
1806
|
+
const contradictionDb = ctx.db;
|
|
1807
|
+
const contradictions = await contradictionDb.query("contradictions").withIndex("by_beliefId", (q) => q.eq("beliefId", beliefNodeId)).collect();
|
|
1407
1808
|
return contradictions.reduce(
|
|
1408
1809
|
(counts, contradiction) => {
|
|
1409
1810
|
const status = contradiction.resolutionStatus ?? contradiction.status ?? "unresolved";
|
|
@@ -1439,18 +1840,16 @@ async function computeEvidenceFreshness(ctx, beliefNodeId, now = Date.now()) {
|
|
|
1439
1840
|
};
|
|
1440
1841
|
}
|
|
1441
1842
|
async function computeDependentBeliefCount(ctx, beliefNodeId) {
|
|
1442
|
-
const incomingEdges = await ctx
|
|
1843
|
+
const incomingEdges = await collectIncomingEdgeRows(ctx, beliefNodeId);
|
|
1443
1844
|
const dependencyEdges = incomingEdges.filter(
|
|
1444
|
-
(edge) => DEPENDENT_EDGE_TYPES.has(edge.edgeType)
|
|
1845
|
+
(edge) => edge.edgeType ? DEPENDENT_EDGE_TYPES.has(edge.edgeType) : false
|
|
1445
1846
|
);
|
|
1446
1847
|
if (dependencyEdges.length === 0) {
|
|
1447
1848
|
return 0;
|
|
1448
1849
|
}
|
|
1449
|
-
const dependentBeliefs = await Promise.all(
|
|
1450
|
-
dependencyEdges.map((edge) => ctx.db.get(edge.fromNodeId))
|
|
1451
|
-
);
|
|
1452
1850
|
const uniqueBeliefIds = /* @__PURE__ */ new Set();
|
|
1453
|
-
for (const
|
|
1851
|
+
for (const edge of dependencyEdges) {
|
|
1852
|
+
const node = await resolveEndpointNode(ctx, sourceEndpointRefs(edge));
|
|
1454
1853
|
if (node && node.nodeType === "belief" && node.status !== "archived" && node.status !== "deleted") {
|
|
1455
1854
|
uniqueBeliefIds.add(String(node._id));
|
|
1456
1855
|
}
|
|
@@ -1460,7 +1859,10 @@ async function computeDependentBeliefCount(ctx, beliefNodeId) {
|
|
|
1460
1859
|
async function snapshotEvidentialMetric(args) {
|
|
1461
1860
|
switch (args.metric) {
|
|
1462
1861
|
case "evidence_count": {
|
|
1463
|
-
const count = await computeEvidenceCountMetric(
|
|
1862
|
+
const count = await computeEvidenceCountMetric(
|
|
1863
|
+
args.ctx,
|
|
1864
|
+
args.beliefNodeId
|
|
1865
|
+
);
|
|
1464
1866
|
return {
|
|
1465
1867
|
metric: args.metric,
|
|
1466
1868
|
value: count,
|
|
@@ -1468,7 +1870,10 @@ async function snapshotEvidentialMetric(args) {
|
|
|
1468
1870
|
};
|
|
1469
1871
|
}
|
|
1470
1872
|
case "contradiction_status": {
|
|
1471
|
-
const counts = await computeContradictionCounts(
|
|
1873
|
+
const counts = await computeContradictionCounts(
|
|
1874
|
+
args.ctx,
|
|
1875
|
+
args.beliefNodeId
|
|
1876
|
+
);
|
|
1472
1877
|
return {
|
|
1473
1878
|
metric: args.metric,
|
|
1474
1879
|
value: counts.activeCount,
|
|
@@ -1488,7 +1893,10 @@ async function snapshotEvidentialMetric(args) {
|
|
|
1488
1893
|
};
|
|
1489
1894
|
}
|
|
1490
1895
|
case "dependent_count": {
|
|
1491
|
-
const count = await computeDependentBeliefCount(
|
|
1896
|
+
const count = await computeDependentBeliefCount(
|
|
1897
|
+
args.ctx,
|
|
1898
|
+
args.beliefNodeId
|
|
1899
|
+
);
|
|
1492
1900
|
return {
|
|
1493
1901
|
metric: args.metric,
|
|
1494
1902
|
value: count,
|
|
@@ -1504,7 +1912,9 @@ async function snapshotEvidentialMetric(args) {
|
|
|
1504
1912
|
}
|
|
1505
1913
|
}
|
|
1506
1914
|
async function evaluateBuiltInEvidentialContract(args) {
|
|
1507
|
-
const config = parseEvidentialEvaluatorConfig(
|
|
1915
|
+
const config = parseEvidentialEvaluatorConfig(
|
|
1916
|
+
args.contract.condition.evaluatorConfig
|
|
1917
|
+
);
|
|
1508
1918
|
const snapshot = await snapshotEvidentialMetric({
|
|
1509
1919
|
ctx: args.ctx,
|
|
1510
1920
|
beliefNodeId: args.belief._id,
|
|
@@ -1512,7 +1922,10 @@ async function evaluateBuiltInEvidentialContract(args) {
|
|
|
1512
1922
|
now: args.now
|
|
1513
1923
|
});
|
|
1514
1924
|
const comparisonSatisfied = snapshot.value !== null && compareMetricValue(config.operator, snapshot.value, config.threshold);
|
|
1515
|
-
const result =
|
|
1925
|
+
const result = resolveComparisonResult(
|
|
1926
|
+
args.contract.direction,
|
|
1927
|
+
comparisonSatisfied
|
|
1928
|
+
);
|
|
1516
1929
|
return {
|
|
1517
1930
|
result,
|
|
1518
1931
|
rationale: buildEvidentialRationale({
|
|
@@ -1532,57 +1945,66 @@ async function evaluateBuiltInEvidentialContract(args) {
|
|
|
1532
1945
|
}
|
|
1533
1946
|
};
|
|
1534
1947
|
}
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
"
|
|
1541
|
-
"
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1948
|
+
function evaluateMetricCheckerContract(args) {
|
|
1949
|
+
return Promise.resolve().then(() => {
|
|
1950
|
+
const config = parseMetricCheckerConfig(
|
|
1951
|
+
args.contract.condition.evaluatorConfig
|
|
1952
|
+
);
|
|
1953
|
+
const input = getEvaluatorInputRecord(args.inputData, "metricData");
|
|
1954
|
+
const metric = typeof input.metric === "string" && input.metric.length > 0 ? input.metric : config.metric;
|
|
1955
|
+
const observedValue = pickFiniteNumber(input, [
|
|
1956
|
+
"observedValue",
|
|
1957
|
+
"currentValue",
|
|
1958
|
+
"metricValue",
|
|
1959
|
+
"value"
|
|
1960
|
+
]) ?? config.observedValue ?? config.currentValue ?? config.metricValue ?? null;
|
|
1961
|
+
if (observedValue === null) {
|
|
1962
|
+
return {
|
|
1963
|
+
result: "inconclusive",
|
|
1964
|
+
rationale: `metric_checker is awaiting data for ${metric ?? args.contract.condition.expression}.`,
|
|
1965
|
+
data: {
|
|
1966
|
+
metric,
|
|
1967
|
+
observedValue: null,
|
|
1968
|
+
operator: config.operator,
|
|
1969
|
+
threshold: config.threshold,
|
|
1970
|
+
unit: config.unit
|
|
1971
|
+
}
|
|
1972
|
+
};
|
|
1973
|
+
}
|
|
1974
|
+
const comparisonSatisfied = compareMetricValue(
|
|
1975
|
+
config.operator,
|
|
1976
|
+
observedValue,
|
|
1977
|
+
config.threshold
|
|
1978
|
+
);
|
|
1979
|
+
const result = resolveComparisonResult(
|
|
1980
|
+
args.contract.direction,
|
|
1981
|
+
comparisonSatisfied
|
|
1982
|
+
);
|
|
1546
1983
|
return {
|
|
1547
|
-
result
|
|
1548
|
-
rationale:
|
|
1984
|
+
result,
|
|
1985
|
+
rationale: buildComparisonRationale({
|
|
1986
|
+
label: metric ?? "metric",
|
|
1987
|
+
observedValue,
|
|
1988
|
+
operator: config.operator,
|
|
1989
|
+
threshold: config.threshold,
|
|
1990
|
+
comparisonSatisfied,
|
|
1991
|
+
result,
|
|
1992
|
+
unit: config.unit
|
|
1993
|
+
}),
|
|
1549
1994
|
data: {
|
|
1550
1995
|
metric,
|
|
1551
|
-
observedValue
|
|
1996
|
+
observedValue,
|
|
1552
1997
|
operator: config.operator,
|
|
1553
1998
|
threshold: config.threshold,
|
|
1554
1999
|
unit: config.unit
|
|
1555
2000
|
}
|
|
1556
2001
|
};
|
|
1557
|
-
}
|
|
1558
|
-
const comparisonSatisfied = compareMetricValue(
|
|
1559
|
-
config.operator,
|
|
1560
|
-
observedValue,
|
|
1561
|
-
config.threshold
|
|
1562
|
-
);
|
|
1563
|
-
const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
|
|
1564
|
-
return {
|
|
1565
|
-
result,
|
|
1566
|
-
rationale: buildComparisonRationale({
|
|
1567
|
-
label: metric ?? "metric",
|
|
1568
|
-
observedValue,
|
|
1569
|
-
operator: config.operator,
|
|
1570
|
-
threshold: config.threshold,
|
|
1571
|
-
comparisonSatisfied,
|
|
1572
|
-
result,
|
|
1573
|
-
unit: config.unit
|
|
1574
|
-
}),
|
|
1575
|
-
data: {
|
|
1576
|
-
metric,
|
|
1577
|
-
observedValue,
|
|
1578
|
-
operator: config.operator,
|
|
1579
|
-
threshold: config.threshold,
|
|
1580
|
-
unit: config.unit
|
|
1581
|
-
}
|
|
1582
|
-
};
|
|
2002
|
+
});
|
|
1583
2003
|
}
|
|
1584
2004
|
async function evaluateReferenceCheckCounterContract(args) {
|
|
1585
|
-
const config = parseReferenceCheckCounterConfig(
|
|
2005
|
+
const config = parseReferenceCheckCounterConfig(
|
|
2006
|
+
args.contract.condition.evaluatorConfig
|
|
2007
|
+
);
|
|
1586
2008
|
const input = getEvaluatorInputRecord(args.inputData, "referenceCheckData");
|
|
1587
2009
|
const tag = typeof input.tag === "string" && input.tag.trim().length > 0 ? input.tag.trim() : config.tag;
|
|
1588
2010
|
const snapshot = await computeTaggedEvidenceCount({
|
|
@@ -1596,7 +2018,10 @@ async function evaluateReferenceCheckCounterContract(args) {
|
|
|
1596
2018
|
snapshot.count,
|
|
1597
2019
|
config.threshold
|
|
1598
2020
|
);
|
|
1599
|
-
const result = resolveComparisonResult(
|
|
2021
|
+
const result = resolveComparisonResult(
|
|
2022
|
+
args.contract.direction,
|
|
2023
|
+
comparisonSatisfied
|
|
2024
|
+
);
|
|
1600
2025
|
return {
|
|
1601
2026
|
result,
|
|
1602
2027
|
rationale: buildComparisonRationale({
|
|
@@ -1618,130 +2043,167 @@ async function evaluateReferenceCheckCounterContract(args) {
|
|
|
1618
2043
|
}
|
|
1619
2044
|
};
|
|
1620
2045
|
}
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
"temporal_deadline requires contract.deadline to be set to a finite timestamp."
|
|
1625
|
-
);
|
|
1626
|
-
}
|
|
1627
|
-
const config = parseTemporalDeadlineConfig(args.contract.condition.evaluatorConfig);
|
|
1628
|
-
const input = getEvaluatorInputRecord(args.inputData, "temporalData");
|
|
1629
|
-
const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
|
|
1630
|
-
const completedAt = pickFiniteNumber(input, [
|
|
1631
|
-
"completedAt",
|
|
1632
|
-
"observedAt",
|
|
1633
|
-
"satisfiedAt",
|
|
1634
|
-
"achievedAt"
|
|
1635
|
-
]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
|
|
1636
|
-
const completed = input.completed === true || config.completed === true || completedAt !== void 0;
|
|
1637
|
-
if (completed) {
|
|
1638
|
-
if (completedAt !== void 0 && completedAt > args.contract.deadline) {
|
|
1639
|
-
return {
|
|
1640
|
-
result: "expired",
|
|
1641
|
-
rationale: `${label} completed at ${completedAt}, after deadline ${args.contract.deadline}.`,
|
|
1642
|
-
data: {
|
|
1643
|
-
label,
|
|
1644
|
-
deadline: args.contract.deadline,
|
|
1645
|
-
completed: true,
|
|
1646
|
-
completedAt,
|
|
1647
|
-
missedDeadline: true,
|
|
1648
|
-
overdueByMs: completedAt - args.contract.deadline
|
|
1649
|
-
}
|
|
1650
|
-
};
|
|
1651
|
-
}
|
|
1652
|
-
const result = args.contract.direction === "falsifies" ? "disconfirmed" : "confirmed";
|
|
2046
|
+
function resolveCompletedTemporalDeadlineResult(args) {
|
|
2047
|
+
const { completedAt, context, deadline, label } = args;
|
|
2048
|
+
if (completedAt !== void 0 && completedAt > deadline) {
|
|
1653
2049
|
return {
|
|
1654
|
-
result,
|
|
1655
|
-
rationale: `${label} completed
|
|
2050
|
+
result: "expired",
|
|
2051
|
+
rationale: `${label} completed at ${completedAt}, after deadline ${deadline}.`,
|
|
1656
2052
|
data: {
|
|
1657
2053
|
label,
|
|
1658
|
-
deadline
|
|
2054
|
+
deadline,
|
|
1659
2055
|
completed: true,
|
|
1660
|
-
completedAt
|
|
1661
|
-
missedDeadline:
|
|
2056
|
+
completedAt,
|
|
2057
|
+
missedDeadline: true,
|
|
2058
|
+
overdueByMs: completedAt - deadline
|
|
1662
2059
|
}
|
|
1663
2060
|
};
|
|
1664
2061
|
}
|
|
1665
|
-
|
|
2062
|
+
const result = context.contract.direction === "falsifies" ? "disconfirmed" : "confirmed";
|
|
2063
|
+
return {
|
|
2064
|
+
result,
|
|
2065
|
+
rationale: `${label} completed before deadline ${deadline}.`,
|
|
2066
|
+
data: {
|
|
2067
|
+
label,
|
|
2068
|
+
deadline,
|
|
2069
|
+
completed: true,
|
|
2070
|
+
completedAt: completedAt ?? null,
|
|
2071
|
+
missedDeadline: false
|
|
2072
|
+
}
|
|
2073
|
+
};
|
|
2074
|
+
}
|
|
2075
|
+
function resolveOpenTemporalDeadlineResult(args) {
|
|
2076
|
+
const { context, deadline, label } = args;
|
|
2077
|
+
if (context.now > deadline) {
|
|
1666
2078
|
return {
|
|
1667
2079
|
result: "expired",
|
|
1668
|
-
rationale: `${label} missed deadline ${
|
|
2080
|
+
rationale: `${label} missed deadline ${deadline}; temporal contract expired.`,
|
|
1669
2081
|
data: {
|
|
1670
2082
|
label,
|
|
1671
|
-
deadline
|
|
2083
|
+
deadline,
|
|
1672
2084
|
completed: false,
|
|
1673
|
-
overdueByMs:
|
|
2085
|
+
overdueByMs: context.now - deadline
|
|
1674
2086
|
}
|
|
1675
2087
|
};
|
|
1676
2088
|
}
|
|
1677
2089
|
return {
|
|
1678
2090
|
result: "inconclusive",
|
|
1679
|
-
rationale: `${label} is still before deadline ${
|
|
2091
|
+
rationale: `${label} is still before deadline ${deadline}; awaiting outcome.`,
|
|
1680
2092
|
data: {
|
|
1681
2093
|
label,
|
|
1682
|
-
deadline
|
|
2094
|
+
deadline,
|
|
1683
2095
|
completed: false,
|
|
1684
|
-
timeRemainingMs:
|
|
2096
|
+
timeRemainingMs: deadline - context.now
|
|
1685
2097
|
}
|
|
1686
2098
|
};
|
|
1687
2099
|
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
2100
|
+
function evaluateTemporalDeadlineContract(args) {
|
|
2101
|
+
return Promise.resolve().then(() => {
|
|
2102
|
+
if (typeof args.contract.deadline !== "number" || !Number.isFinite(args.contract.deadline)) {
|
|
2103
|
+
throw new Error(
|
|
2104
|
+
"temporal_deadline requires contract.deadline to be set to a finite timestamp."
|
|
2105
|
+
);
|
|
2106
|
+
}
|
|
2107
|
+
const deadline = args.contract.deadline;
|
|
2108
|
+
const config = parseTemporalDeadlineConfig(
|
|
2109
|
+
args.contract.condition.evaluatorConfig
|
|
2110
|
+
);
|
|
2111
|
+
const input = getEvaluatorInputRecord(args.inputData, "temporalData");
|
|
2112
|
+
const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
|
|
2113
|
+
const completedAt = pickFiniteNumber(input, [
|
|
2114
|
+
"completedAt",
|
|
2115
|
+
"observedAt",
|
|
2116
|
+
"satisfiedAt",
|
|
2117
|
+
"achievedAt"
|
|
2118
|
+
]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
|
|
2119
|
+
const completed = input.completed === true || config.completed === true || completedAt !== void 0;
|
|
2120
|
+
if (completed) {
|
|
2121
|
+
return resolveCompletedTemporalDeadlineResult({
|
|
2122
|
+
completedAt,
|
|
2123
|
+
context: args,
|
|
2124
|
+
deadline,
|
|
2125
|
+
label
|
|
2126
|
+
});
|
|
2127
|
+
}
|
|
2128
|
+
return resolveOpenTemporalDeadlineResult({
|
|
2129
|
+
context: args,
|
|
2130
|
+
deadline,
|
|
2131
|
+
label
|
|
2132
|
+
});
|
|
2133
|
+
});
|
|
2134
|
+
}
|
|
2135
|
+
function evaluateMarketIndexComparatorContract(args) {
|
|
2136
|
+
return Promise.resolve().then(() => {
|
|
2137
|
+
const config = parseMarketIndexComparatorConfig(
|
|
2138
|
+
args.contract.condition.evaluatorConfig
|
|
2139
|
+
);
|
|
2140
|
+
const input = getEvaluatorInputRecord(args.inputData, "marketIndexData");
|
|
2141
|
+
const subject = typeof input.subject === "string" && input.subject.length > 0 ? input.subject : config.subject;
|
|
2142
|
+
const benchmark = typeof input.benchmark === "string" && input.benchmark.length > 0 ? input.benchmark : config.benchmark;
|
|
2143
|
+
const subjectValue = pickFiniteNumber(input, ["subjectValue", "primaryValue", "leftValue"]) ?? config.subjectValue ?? config.primaryValue ?? null;
|
|
2144
|
+
const benchmarkValue = pickFiniteNumber(input, [
|
|
2145
|
+
"benchmarkValue",
|
|
2146
|
+
"comparisonValue",
|
|
2147
|
+
"rightValue"
|
|
2148
|
+
]) ?? config.benchmarkValue ?? config.comparisonValue ?? null;
|
|
2149
|
+
if (subjectValue === null || benchmarkValue === null) {
|
|
2150
|
+
return {
|
|
2151
|
+
result: "inconclusive",
|
|
2152
|
+
rationale: "market_index_comparator is awaiting both subject and benchmark values.",
|
|
2153
|
+
data: {
|
|
2154
|
+
subject,
|
|
2155
|
+
subjectValue,
|
|
2156
|
+
benchmark,
|
|
2157
|
+
benchmarkValue,
|
|
2158
|
+
operator: config.operator,
|
|
2159
|
+
threshold: config.threshold
|
|
2160
|
+
}
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
if (benchmarkValue === 0) {
|
|
2164
|
+
throw new Error(
|
|
2165
|
+
"market_index_comparator cannot compare against a zero benchmark value."
|
|
2166
|
+
);
|
|
2167
|
+
}
|
|
2168
|
+
const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
|
|
2169
|
+
const comparisonSatisfied = compareMetricValue(
|
|
2170
|
+
config.operator,
|
|
2171
|
+
differentialPercent,
|
|
2172
|
+
config.threshold
|
|
2173
|
+
);
|
|
2174
|
+
const result = resolveComparisonResult(
|
|
2175
|
+
args.contract.direction,
|
|
2176
|
+
comparisonSatisfied
|
|
2177
|
+
);
|
|
1696
2178
|
return {
|
|
1697
|
-
result
|
|
1698
|
-
rationale:
|
|
2179
|
+
result,
|
|
2180
|
+
rationale: buildComparisonRationale({
|
|
2181
|
+
label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
|
|
2182
|
+
observedValue: differentialPercent,
|
|
2183
|
+
operator: config.operator,
|
|
2184
|
+
threshold: config.threshold,
|
|
2185
|
+
comparisonSatisfied,
|
|
2186
|
+
result,
|
|
2187
|
+
unit: "%"
|
|
2188
|
+
}),
|
|
1699
2189
|
data: {
|
|
1700
2190
|
subject,
|
|
1701
2191
|
subjectValue,
|
|
1702
2192
|
benchmark,
|
|
1703
2193
|
benchmarkValue,
|
|
2194
|
+
differentialPercent,
|
|
1704
2195
|
operator: config.operator,
|
|
1705
2196
|
threshold: config.threshold
|
|
1706
2197
|
}
|
|
1707
2198
|
};
|
|
1708
|
-
}
|
|
1709
|
-
if (benchmarkValue === 0) {
|
|
1710
|
-
throw new Error(
|
|
1711
|
-
"market_index_comparator cannot compare against a zero benchmark value."
|
|
1712
|
-
);
|
|
1713
|
-
}
|
|
1714
|
-
const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
|
|
1715
|
-
const comparisonSatisfied = compareMetricValue(
|
|
1716
|
-
config.operator,
|
|
1717
|
-
differentialPercent,
|
|
1718
|
-
config.threshold
|
|
1719
|
-
);
|
|
1720
|
-
const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
|
|
1721
|
-
return {
|
|
1722
|
-
result,
|
|
1723
|
-
rationale: buildComparisonRationale({
|
|
1724
|
-
label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
|
|
1725
|
-
observedValue: differentialPercent,
|
|
1726
|
-
operator: config.operator,
|
|
1727
|
-
threshold: config.threshold,
|
|
1728
|
-
comparisonSatisfied,
|
|
1729
|
-
result,
|
|
1730
|
-
unit: "%"
|
|
1731
|
-
}),
|
|
1732
|
-
data: {
|
|
1733
|
-
subject,
|
|
1734
|
-
subjectValue,
|
|
1735
|
-
benchmark,
|
|
1736
|
-
benchmarkValue,
|
|
1737
|
-
differentialPercent,
|
|
1738
|
-
operator: config.operator,
|
|
1739
|
-
threshold: config.threshold
|
|
1740
|
-
}
|
|
1741
|
-
};
|
|
2199
|
+
});
|
|
1742
2200
|
}
|
|
1743
2201
|
var METRIC_COMPARATOR_EVALUATOR_NAMES = {
|
|
1744
|
-
evidentialAliases: /* @__PURE__ */ new Set([
|
|
2202
|
+
evidentialAliases: /* @__PURE__ */ new Set([
|
|
2203
|
+
"evidential",
|
|
2204
|
+
"built_in_evidential",
|
|
2205
|
+
"builtin_evidential"
|
|
2206
|
+
]),
|
|
1745
2207
|
metricChecker: "metric_checker",
|
|
1746
2208
|
referenceCheckCounter: "reference_check_counter",
|
|
1747
2209
|
temporalDeadline: "temporal_deadline",
|
|
@@ -1749,6 +2211,8 @@ var METRIC_COMPARATOR_EVALUATOR_NAMES = {
|
|
|
1749
2211
|
};
|
|
1750
2212
|
|
|
1751
2213
|
// src/evaluators/shared.ts
|
|
2214
|
+
var WINDOWS_PATH_SEPARATORS = /\\/g;
|
|
2215
|
+
var LEADING_DOT_SLASH = /^\.\//;
|
|
1752
2216
|
function asArray(value) {
|
|
1753
2217
|
return Array.isArray(value) ? value : [];
|
|
1754
2218
|
}
|
|
@@ -1790,7 +2254,7 @@ function extractTextCandidates(value) {
|
|
|
1790
2254
|
return Array.from(new Set(candidates));
|
|
1791
2255
|
}
|
|
1792
2256
|
function normalizeFilePath(value) {
|
|
1793
|
-
return value.replace(
|
|
2257
|
+
return value.replace(WINDOWS_PATH_SEPARATORS, "/").replace(LEADING_DOT_SLASH, "");
|
|
1794
2258
|
}
|
|
1795
2259
|
function normalizeToolResultEnvelope(value) {
|
|
1796
2260
|
const record = asRecord(value);
|
|
@@ -1844,7 +2308,7 @@ function somePatternMatches(filePath, patterns) {
|
|
|
1844
2308
|
return patterns.some((pattern) => patternMatchesPath(filePath, pattern));
|
|
1845
2309
|
}
|
|
1846
2310
|
|
|
1847
|
-
// src/evaluators/
|
|
2311
|
+
// src/evaluators/lint-checker-evaluator.ts
|
|
1848
2312
|
function parseConfig(condition) {
|
|
1849
2313
|
const record = asRecord(condition.evaluatorConfig);
|
|
1850
2314
|
if (!record) {
|
|
@@ -1916,7 +2380,10 @@ var lintCheckerEvaluator = {
|
|
|
1916
2380
|
}
|
|
1917
2381
|
const envelope = normalizeToolResultEnvelope(args.resultData);
|
|
1918
2382
|
const exitCode = asNumber(envelope.exitCode);
|
|
1919
|
-
const matchedDiagnostics = getMatchedDiagnostics(
|
|
2383
|
+
const matchedDiagnostics = getMatchedDiagnostics(
|
|
2384
|
+
args.contract,
|
|
2385
|
+
args.resultData
|
|
2386
|
+
);
|
|
1920
2387
|
if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
|
|
1921
2388
|
return {
|
|
1922
2389
|
result: "inconclusive",
|
|
@@ -1942,7 +2409,7 @@ var lintCheckerEvaluator = {
|
|
|
1942
2409
|
}
|
|
1943
2410
|
};
|
|
1944
2411
|
|
|
1945
|
-
// src/evaluators/
|
|
2412
|
+
// src/evaluators/sentry-checker-evaluator.ts
|
|
1946
2413
|
function parseConfig2(condition) {
|
|
1947
2414
|
const record = asRecord(condition.evaluatorConfig);
|
|
1948
2415
|
if (!record) {
|
|
@@ -2027,7 +2494,7 @@ var sentryCheckerEvaluator = {
|
|
|
2027
2494
|
}
|
|
2028
2495
|
};
|
|
2029
2496
|
|
|
2030
|
-
// src/evaluators/
|
|
2497
|
+
// src/evaluators/test-runner-evaluator.ts
|
|
2031
2498
|
function parseConfig3(condition) {
|
|
2032
2499
|
const record = asRecord(condition.evaluatorConfig);
|
|
2033
2500
|
if (!record) {
|
|
@@ -2173,7 +2640,7 @@ var testRunnerEvaluator = {
|
|
|
2173
2640
|
}
|
|
2174
2641
|
};
|
|
2175
2642
|
|
|
2176
|
-
// src/evaluators/
|
|
2643
|
+
// src/evaluators/tsc-checker-evaluator.ts
|
|
2177
2644
|
function parseConfig4(condition) {
|
|
2178
2645
|
const record = asRecord(condition.evaluatorConfig);
|
|
2179
2646
|
if (!record) {
|
|
@@ -2258,7 +2725,10 @@ var tscCheckerEvaluator = {
|
|
|
2258
2725
|
}
|
|
2259
2726
|
const envelope = normalizeToolResultEnvelope(args.resultData);
|
|
2260
2727
|
const exitCode = asNumber(envelope.exitCode);
|
|
2261
|
-
const matchedDiagnostics = getMatchedDiagnostics2(
|
|
2728
|
+
const matchedDiagnostics = getMatchedDiagnostics2(
|
|
2729
|
+
args.contract,
|
|
2730
|
+
args.resultData
|
|
2731
|
+
);
|
|
2262
2732
|
if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
|
|
2263
2733
|
return {
|
|
2264
2734
|
result: "inconclusive",
|
|
@@ -2302,6 +2772,18 @@ var BUILT_IN_REFERENCE_CHECK_COUNTER2 = METRIC_COMPARATOR_EVALUATOR_NAMES.refere
|
|
|
2302
2772
|
var BUILT_IN_TEMPORAL_DEADLINE2 = METRIC_COMPARATOR_EVALUATOR_NAMES.temporalDeadline;
|
|
2303
2773
|
var BUILT_IN_MARKET_INDEX_COMPARATOR2 = METRIC_COMPARATOR_EVALUATOR_NAMES.marketIndexComparator;
|
|
2304
2774
|
var MAX_CONTRACT_EVALUATION_BATCH_SIZE = 50;
|
|
2775
|
+
function confidenceSeed(args) {
|
|
2776
|
+
if (typeof args.currentConfidence === "number") {
|
|
2777
|
+
return args.currentConfidence;
|
|
2778
|
+
}
|
|
2779
|
+
if (typeof args.beliefConfidence === "number") {
|
|
2780
|
+
return args.beliefConfidence;
|
|
2781
|
+
}
|
|
2782
|
+
return 0.5;
|
|
2783
|
+
}
|
|
2784
|
+
function contractDocId(contract) {
|
|
2785
|
+
return contract._id;
|
|
2786
|
+
}
|
|
2305
2787
|
function clearEpistemicEvaluators() {
|
|
2306
2788
|
evaluatorRegistry.clear();
|
|
2307
2789
|
ensureBuiltInEvaluators();
|
|
@@ -2394,7 +2876,10 @@ async function executeContractEvaluation(args) {
|
|
|
2394
2876
|
rationale: `No epistemic evaluator registered for "${args.contract.condition.evaluator}".`
|
|
2395
2877
|
};
|
|
2396
2878
|
}
|
|
2397
|
-
const confidenceBefore =
|
|
2879
|
+
const confidenceBefore = confidenceSeed({
|
|
2880
|
+
beliefConfidence: args.belief.confidence,
|
|
2881
|
+
currentConfidence: args.currentConfidence
|
|
2882
|
+
});
|
|
2398
2883
|
const modulationPlan = deriveContractModulationPlan({
|
|
2399
2884
|
currentConfidence: confidenceBefore,
|
|
2400
2885
|
modulation: args.contract.modulation,
|
|
@@ -2434,16 +2919,16 @@ async function executeContractEvaluation(args) {
|
|
|
2434
2919
|
modulationRationale: evaluation.rationale,
|
|
2435
2920
|
topicId: args.contract.topicId
|
|
2436
2921
|
});
|
|
2437
|
-
const nextStatus = deriveContractStatus(
|
|
2438
|
-
|
|
2439
|
-
args.contract.
|
|
2440
|
-
{
|
|
2441
|
-
status: nextStatus,
|
|
2442
|
-
lastEvaluatedAt: args.now,
|
|
2443
|
-
evaluationCount: (args.contract.evaluationCount ?? 0) + 1,
|
|
2444
|
-
updatedAt: args.now
|
|
2445
|
-
}
|
|
2922
|
+
const nextStatus = deriveContractStatus(
|
|
2923
|
+
evaluation.result,
|
|
2924
|
+
args.contract.status
|
|
2446
2925
|
);
|
|
2926
|
+
await args.ctx.db.patch(contractDocId(args.contract), {
|
|
2927
|
+
status: nextStatus,
|
|
2928
|
+
lastEvaluatedAt: args.now,
|
|
2929
|
+
evaluationCount: (args.contract.evaluationCount ?? 0) + 1,
|
|
2930
|
+
updatedAt: args.now
|
|
2931
|
+
});
|
|
2447
2932
|
return {
|
|
2448
2933
|
evaluationId,
|
|
2449
2934
|
result: evaluation.result,
|
|
@@ -2528,7 +3013,8 @@ async function evaluateContractsForTriggerBatch(args) {
|
|
|
2528
3013
|
};
|
|
2529
3014
|
}
|
|
2530
3015
|
async function loadContractsForBelief(args) {
|
|
2531
|
-
|
|
3016
|
+
const rows = await args.ctx.db.query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
|
|
3017
|
+
return rows;
|
|
2532
3018
|
}
|
|
2533
3019
|
async function loadContractsForTrigger(args) {
|
|
2534
3020
|
const contracts = await loadContractsForBelief(args);
|