@lucern/graph-primitives 1.0.0 → 1.0.1

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.
Files changed (202) hide show
  1. package/README.md +13 -12
  2. package/dist/beliefDecay.js +24 -17
  3. package/dist/beliefDecay.js.map +1 -1
  4. package/dist/beliefEvidenceLinks.js +32 -8
  5. package/dist/beliefEvidenceLinks.js.map +1 -1
  6. package/dist/confidencePropagationDispatch.js.map +1 -1
  7. package/dist/contradictions.js +32 -9
  8. package/dist/contradictions.js.map +1 -1
  9. package/dist/convex.d.ts +55 -12
  10. package/dist/convex.js.map +1 -1
  11. package/dist/edgeValidation.d.ts +25 -2
  12. package/dist/edges/index.d.ts +9 -2
  13. package/dist/edges/index.js.map +1 -1
  14. package/dist/edges/propagationTypes.d.ts +2 -3
  15. package/dist/edges/propagationTypes.js.map +1 -1
  16. package/dist/entityBridge.js +10 -3
  17. package/dist/entityBridge.js.map +1 -1
  18. package/dist/entityLifecycle.js +15 -3
  19. package/dist/entityLifecycle.js.map +1 -1
  20. package/dist/epistemicAnswers.js.map +1 -1
  21. package/dist/epistemicBeliefs.admin.d.ts +36 -0
  22. package/dist/epistemicBeliefs.admin.js +745 -0
  23. package/dist/epistemicBeliefs.admin.js.map +1 -0
  24. package/dist/epistemicBeliefs.backfills.d.ts +62 -0
  25. package/dist/epistemicBeliefs.backfills.js +1004 -0
  26. package/dist/epistemicBeliefs.backfills.js.map +1 -0
  27. package/dist/epistemicBeliefs.confidence.d.ts +45 -0
  28. package/dist/epistemicBeliefs.confidence.js +1285 -0
  29. package/dist/epistemicBeliefs.confidence.js.map +1 -0
  30. package/dist/epistemicBeliefs.core.d.ts +35 -0
  31. package/dist/epistemicBeliefs.core.js +1508 -0
  32. package/dist/epistemicBeliefs.core.js.map +1 -0
  33. package/dist/epistemicBeliefs.d.ts +12 -3
  34. package/dist/epistemicBeliefs.helpers.d.ts +168 -0
  35. package/dist/epistemicBeliefs.helpers.js +1060 -0
  36. package/dist/epistemicBeliefs.helpers.js.map +1 -0
  37. package/dist/epistemicBeliefs.internal.d.ts +30 -0
  38. package/dist/epistemicBeliefs.internal.js +1329 -0
  39. package/dist/epistemicBeliefs.internal.js.map +1 -0
  40. package/dist/epistemicBeliefs.js +1196 -1184
  41. package/dist/epistemicBeliefs.js.map +1 -1
  42. package/dist/epistemicBeliefs.lifecycle.d.ts +19 -0
  43. package/dist/epistemicBeliefs.lifecycle.js +1608 -0
  44. package/dist/epistemicBeliefs.lifecycle.js.map +1 -0
  45. package/dist/epistemicBeliefs.links.d.ts +30 -0
  46. package/dist/epistemicBeliefs.links.js +761 -0
  47. package/dist/epistemicBeliefs.links.js.map +1 -0
  48. package/dist/epistemicBeliefs.queries.d.ts +16 -0
  49. package/dist/epistemicBeliefs.queries.js +90 -0
  50. package/dist/epistemicBeliefs.queries.js.map +1 -0
  51. package/dist/epistemicContractHelpers.d.ts +1 -1
  52. package/dist/epistemicContractHelpers.js +1 -1
  53. package/dist/epistemicContracts.d.ts +5 -76
  54. package/dist/epistemicContracts.evaluators.d.ts +36 -0
  55. package/dist/epistemicContracts.evaluators.js +2506 -0
  56. package/dist/epistemicContracts.evaluators.js.map +1 -0
  57. package/dist/epistemicContracts.handlers.d.ts +40 -0
  58. package/dist/epistemicContracts.handlers.js +3029 -0
  59. package/dist/epistemicContracts.handlers.js.map +1 -0
  60. package/dist/epistemicContracts.js +2006 -5281
  61. package/dist/epistemicContracts.js.map +1 -1
  62. package/dist/epistemicContracts.metrics.d.ts +26 -0
  63. package/dist/epistemicContracts.metrics.js +427 -0
  64. package/dist/epistemicContracts.metrics.js.map +1 -0
  65. package/dist/epistemicContracts.types.d.ts +159 -0
  66. package/dist/epistemicContracts.types.js +3 -0
  67. package/dist/epistemicContracts.types.js.map +1 -0
  68. package/dist/epistemicEdgeCreation.d.ts +73 -0
  69. package/dist/epistemicEdgeCreation.js +450 -0
  70. package/dist/epistemicEdgeCreation.js.map +1 -0
  71. package/dist/epistemicEdges-BF-cn4i3.d.ts +43 -0
  72. package/dist/epistemicEdges.d.ts +8 -1
  73. package/dist/epistemicEdges.handlers.d.ts +20 -0
  74. package/dist/epistemicEdges.handlers.js +289 -0
  75. package/dist/epistemicEdges.handlers.js.map +1 -0
  76. package/dist/epistemicEdges.helpers.d.ts +27 -0
  77. package/dist/epistemicEdges.helpers.js +162 -0
  78. package/dist/epistemicEdges.helpers.js.map +1 -0
  79. package/dist/epistemicEdges.js +797 -875
  80. package/dist/epistemicEdges.js.map +1 -1
  81. package/dist/epistemicEdges.mutations.d.ts +39 -0
  82. package/dist/epistemicEdges.mutations.js +1365 -0
  83. package/dist/epistemicEdges.mutations.js.map +1 -0
  84. package/dist/epistemicEdges.queries.d.ts +95 -0
  85. package/dist/epistemicEdges.queries.js +851 -0
  86. package/dist/epistemicEdges.queries.js.map +1 -0
  87. package/dist/epistemicEdges.types.d.ts +32 -0
  88. package/dist/epistemicEdges.types.js +3 -0
  89. package/dist/epistemicEdges.types.js.map +1 -0
  90. package/dist/epistemicEvidence-DvfchNt7.d.ts +46 -0
  91. package/dist/epistemicEvidence.d.ts +5 -2
  92. package/dist/epistemicEvidence.js +801 -807
  93. package/dist/epistemicEvidence.js.map +1 -1
  94. package/dist/epistemicEvidenceHelpers.d.ts +71 -0
  95. package/dist/epistemicEvidenceHelpers.js +769 -0
  96. package/dist/epistemicEvidenceHelpers.js.map +1 -0
  97. package/dist/epistemicEvidenceMutations.d.ts +10 -0
  98. package/dist/epistemicEvidenceMutations.js +1421 -0
  99. package/dist/epistemicEvidenceMutations.js.map +1 -0
  100. package/dist/epistemicEvidenceQueries.d.ts +10 -0
  101. package/dist/epistemicEvidenceQueries.js +1049 -0
  102. package/dist/epistemicEvidenceQueries.js.map +1 -0
  103. package/dist/epistemicHelpers.d.ts +4 -2
  104. package/dist/epistemicHelpers.js +132 -127
  105. package/dist/epistemicHelpers.js.map +1 -1
  106. package/dist/epistemicLayerRules.d.ts +138 -0
  107. package/dist/epistemicLayerRules.js +481 -0
  108. package/dist/epistemicLayerRules.js.map +1 -0
  109. package/dist/epistemicLinking.js +1 -1
  110. package/dist/epistemicLinking.js.map +1 -1
  111. package/dist/epistemicNodeCreation.d.ts +101 -0
  112. package/dist/epistemicNodeCreation.js +709 -0
  113. package/dist/epistemicNodeCreation.js.map +1 -0
  114. package/dist/epistemicNodes-BCQxpYx_.d.ts +54 -0
  115. package/dist/epistemicNodes.d.ts +5 -1
  116. package/dist/epistemicNodes.helpers.d.ts +51 -0
  117. package/dist/epistemicNodes.helpers.js +73 -0
  118. package/dist/epistemicNodes.helpers.js.map +1 -0
  119. package/dist/epistemicNodes.internal.d.ts +34 -0
  120. package/dist/epistemicNodes.internal.js +658 -0
  121. package/dist/epistemicNodes.internal.js.map +1 -0
  122. package/dist/epistemicNodes.js +698 -693
  123. package/dist/epistemicNodes.js.map +1 -1
  124. package/dist/epistemicNodes.mutations.d.ts +34 -0
  125. package/dist/epistemicNodes.mutations.js +1153 -0
  126. package/dist/epistemicNodes.mutations.js.map +1 -0
  127. package/dist/epistemicNodes.queries.d.ts +36 -0
  128. package/dist/epistemicNodes.queries.js +619 -0
  129. package/dist/epistemicNodes.queries.js.map +1 -0
  130. package/dist/epistemicNodes.validators.d.ts +23 -0
  131. package/dist/epistemicNodes.validators.js +105 -0
  132. package/dist/epistemicNodes.validators.js.map +1 -0
  133. package/dist/epistemicQuestions-bwHd2FWE.d.ts +68 -0
  134. package/dist/epistemicQuestions.conviction.d.ts +52 -0
  135. package/dist/epistemicQuestions.conviction.js +1389 -0
  136. package/dist/epistemicQuestions.conviction.js.map +1 -0
  137. package/dist/epistemicQuestions.create.d.ts +29 -0
  138. package/dist/epistemicQuestions.create.js +1300 -0
  139. package/dist/epistemicQuestions.create.js.map +1 -0
  140. package/dist/epistemicQuestions.d.ts +10 -2
  141. package/dist/epistemicQuestions.evidence.d.ts +22 -0
  142. package/dist/epistemicQuestions.evidence.js +929 -0
  143. package/dist/epistemicQuestions.evidence.js.map +1 -0
  144. package/dist/epistemicQuestions.helpers.d.ts +69 -0
  145. package/dist/epistemicQuestions.helpers.js +824 -0
  146. package/dist/epistemicQuestions.helpers.js.map +1 -0
  147. package/dist/epistemicQuestions.js +2435 -2430
  148. package/dist/epistemicQuestions.js.map +1 -1
  149. package/dist/epistemicQuestions.lifecycle.d.ts +24 -0
  150. package/dist/epistemicQuestions.lifecycle.js +838 -0
  151. package/dist/epistemicQuestions.lifecycle.js.map +1 -0
  152. package/dist/epistemicQuestions.queries.d.ts +41 -0
  153. package/dist/epistemicQuestions.queries.js +1013 -0
  154. package/dist/epistemicQuestions.queries.js.map +1 -0
  155. package/dist/epistemicQuestions.sprint.d.ts +22 -0
  156. package/dist/epistemicQuestions.sprint.js +757 -0
  157. package/dist/epistemicQuestions.sprint.js.map +1 -0
  158. package/dist/epistemicQuestions.tail.d.ts +42 -0
  159. package/dist/epistemicQuestions.tail.js +1345 -0
  160. package/dist/epistemicQuestions.tail.js.map +1 -0
  161. package/dist/epistemicSources.js +6 -2
  162. package/dist/epistemicSources.js.map +1 -1
  163. package/dist/evaluators/index.d.ts +2 -2
  164. package/dist/evaluators/index.js +45 -5320
  165. package/dist/evaluators/index.js.map +1 -1
  166. package/dist/evaluators/lintCheckerEvaluator.d.ts +1 -1
  167. package/dist/evaluators/sentryCheckerEvaluator.d.ts +1 -1
  168. package/dist/evaluators/testRunnerEvaluator.d.ts +1 -1
  169. package/dist/evaluators/tscCheckerEvaluator.d.ts +1 -1
  170. package/dist/{graphTypes-CpgIuCdo.d.ts → graphTypes-B8VaIjnl.d.ts} +1 -1
  171. package/dist/graphTypes.d.ts +1 -1
  172. package/dist/{helpers-BYHIk5vU.d.ts → helpers-DNYfg6mo.d.ts} +2 -3
  173. package/dist/helpers.d.ts +2 -2
  174. package/dist/helpers.js.map +1 -1
  175. package/dist/{index-Dq-7R-gi.d.ts → index-C-Kyd7hD.d.ts} +1 -1
  176. package/dist/index.d.ts +160 -14
  177. package/dist/index.js +12291 -13001
  178. package/dist/index.js.map +1 -1
  179. package/dist/logicalRoleInference.js.map +1 -1
  180. package/dist/ontologyApproval.js +1 -1
  181. package/dist/ontologyApproval.js.map +1 -1
  182. package/dist/ontologyDefinitions.js +25 -7
  183. package/dist/ontologyDefinitions.js.map +1 -1
  184. package/dist/ontologyRegistry.js.map +1 -1
  185. package/dist/projectionReconciliation.js.map +1 -1
  186. package/dist/questionEvidenceLinks.js +28 -7
  187. package/dist/questionEvidenceLinks.js.map +1 -1
  188. package/dist/resolvers.js.map +1 -1
  189. package/dist/scopeResolverCompat.js.map +1 -1
  190. package/dist/topicProjectOverlay.js.map +1 -1
  191. package/dist/topicScope.js.map +1 -1
  192. package/dist/workflowBridge.js.map +1 -1
  193. package/dist/workspaceIsolation.js.map +1 -1
  194. package/package.json +4 -5
  195. package/dist/edgeValidation-CeI0wc0r.d.ts +0 -35
  196. package/dist/epistemicBeliefs-DzKjZAeC.d.ts +0 -377
  197. package/dist/epistemicEdges-CvlKnEyy.d.ts +0 -191
  198. package/dist/epistemicEvidence-xw6UUrwh.d.ts +0 -128
  199. package/dist/epistemicHelpers-DevrYgPN.d.ts +0 -329
  200. package/dist/epistemicNodes-DjSUfvyD.d.ts +0 -167
  201. package/dist/epistemicQuestions-B_nUclrH.d.ts +0 -214
  202. package/dist/index-Dct1T70K.d.ts +0 -25
@@ -0,0 +1,26 @@
1
+ import { Id } from './convex.js';
2
+ import { ContractReadCtx, ContradictionStatusCounts, EvidenceFreshness, EpistemicEvaluatorContext, EpistemicEvaluatorResult } from './epistemicContracts.types.js';
3
+ import 'convex/values';
4
+ import '@lucern/confidence';
5
+
6
+ /** Metric helpers and evidential snapshots used by contract evaluators. */
7
+
8
+ declare function computeEvidenceCountMetric(ctx: ContractReadCtx, beliefNodeId: Id<"epistemicNodes">): Promise<number>;
9
+ declare function computeContradictionCounts(ctx: ContractReadCtx, beliefNodeId: Id<"epistemicNodes">): Promise<ContradictionStatusCounts>;
10
+ declare function computeEvidenceFreshness(ctx: ContractReadCtx, beliefNodeId: Id<"epistemicNodes">, now?: number): Promise<EvidenceFreshness>;
11
+ declare function computeDependentBeliefCount(ctx: ContractReadCtx, beliefNodeId: Id<"epistemicNodes">): Promise<number>;
12
+ declare function evaluateBuiltInEvidentialContract(args: EpistemicEvaluatorContext): Promise<EpistemicEvaluatorResult>;
13
+ declare function evaluateMetricCheckerContract(args: EpistemicEvaluatorContext): Promise<EpistemicEvaluatorResult>;
14
+ declare function evaluateReferenceCheckCounterContract(args: EpistemicEvaluatorContext): Promise<EpistemicEvaluatorResult>;
15
+ declare function evaluateTemporalDeadlineContract(args: EpistemicEvaluatorContext): Promise<EpistemicEvaluatorResult>;
16
+ declare function evaluateMarketIndexComparatorContract(args: EpistemicEvaluatorContext): Promise<EpistemicEvaluatorResult>;
17
+ declare const METRIC_COMPARATOR_EVALUATOR_NAMES: {
18
+ evidential: string;
19
+ evidentialAliases: Set<string>;
20
+ metricChecker: string;
21
+ referenceCheckCounter: string;
22
+ temporalDeadline: string;
23
+ marketIndexComparator: string;
24
+ };
25
+
26
+ export { METRIC_COMPARATOR_EVALUATOR_NAMES, computeContradictionCounts, computeDependentBeliefCount, computeEvidenceCountMetric, computeEvidenceFreshness, evaluateBuiltInEvidentialContract, evaluateMarketIndexComparatorContract, evaluateMetricCheckerContract, evaluateReferenceCheckCounterContract, evaluateTemporalDeadlineContract };
@@ -0,0 +1,427 @@
1
+ import { parseEvidentialEvaluatorConfig, compareMetricValue, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, resolveComparisonResult, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig } from '@lucern/confidence';
2
+
3
+ // src/epistemicContractHelpers.ts
4
+
5
+ // src/epistemicContracts.metrics.ts
6
+ var ACTIVE_CONTRADICTION_STATUSES = /* @__PURE__ */ new Set([
7
+ "unresolved",
8
+ "investigating",
9
+ "accepted_as_permanent"
10
+ ]);
11
+ var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set([
12
+ "depends_on"
13
+ ]);
14
+ function classifyContradictionStatus(status) {
15
+ if (typeof status !== "string") {
16
+ return "active";
17
+ }
18
+ if (ACTIVE_CONTRADICTION_STATUSES.has(status)) {
19
+ return "active";
20
+ }
21
+ if (status === "resolved_support" || status === "resolved_contra" || status === "belief_forked") {
22
+ return "resolved";
23
+ }
24
+ return "resolved";
25
+ }
26
+ function getEdgeTimestamp(edge) {
27
+ if (typeof edge.updatedAt === "number") {
28
+ return edge.updatedAt;
29
+ }
30
+ if (typeof edge.createdAt === "number") {
31
+ return edge.createdAt;
32
+ }
33
+ if (typeof edge._creationTime === "number") {
34
+ return edge._creationTime;
35
+ }
36
+ return null;
37
+ }
38
+ async function getEvidenceLinks(ctx, beliefNodeId) {
39
+ const edges = await ctx.db.query("epistemicEdges").withIndex(
40
+ "by_to_type",
41
+ (q) => q.eq("toNodeId", beliefNodeId).eq("edgeType", "informs")
42
+ ).collect();
43
+ if (edges.length === 0) {
44
+ return [];
45
+ }
46
+ const nodes = await Promise.all(edges.map((edge) => ctx.db.get(edge.fromNodeId)));
47
+ return edges.flatMap((edge, index) => {
48
+ const node = nodes[index];
49
+ if (!node || node.nodeType !== "evidence" || node.status === "archived") {
50
+ return [];
51
+ }
52
+ return [{ edge, node }];
53
+ });
54
+ }
55
+ function getEvidenceTags(node) {
56
+ const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : null;
57
+ const tags = metadata?.tags;
58
+ if (!Array.isArray(tags)) {
59
+ return [];
60
+ }
61
+ return tags.filter((tag) => typeof tag === "string");
62
+ }
63
+ async function computeEvidenceCountMetric(ctx, beliefNodeId) {
64
+ return (await getEvidenceLinks(ctx, beliefNodeId)).length;
65
+ }
66
+ async function computeTaggedEvidenceCount(args) {
67
+ const expectedTag = args.caseSensitive ? args.tag : args.tag.toLowerCase();
68
+ const matchedEvidenceIds = (await getEvidenceLinks(args.ctx, args.beliefNodeId)).filter(
69
+ ({ node }) => getEvidenceTags(node).some(
70
+ (tag) => (args.caseSensitive ? tag : tag.toLowerCase()) === expectedTag
71
+ )
72
+ ).map(({ node }) => String(node._id));
73
+ return {
74
+ count: matchedEvidenceIds.length,
75
+ matchedEvidenceIds
76
+ };
77
+ }
78
+ async function computeContradictionCounts(ctx, beliefNodeId) {
79
+ const contradictions = await ctx.db.query("contradictions").withIndex("by_beliefId", (q) => q.eq("beliefId", beliefNodeId)).collect();
80
+ return contradictions.reduce(
81
+ (counts, contradiction) => {
82
+ const status = contradiction.resolutionStatus ?? contradiction.status ?? "unresolved";
83
+ if (classifyContradictionStatus(status) === "active") {
84
+ counts.activeCount += 1;
85
+ } else {
86
+ counts.resolvedCount += 1;
87
+ }
88
+ return counts;
89
+ },
90
+ { activeCount: 0, resolvedCount: 0 }
91
+ );
92
+ }
93
+ async function computeEvidenceFreshness(ctx, beliefNodeId, now = Date.now()) {
94
+ const timestamps = (await getEvidenceLinks(ctx, beliefNodeId)).map(({ edge }) => getEdgeTimestamp(edge)).filter((value) => value !== null);
95
+ if (timestamps.length === 0) {
96
+ return {
97
+ newestAgeMs: null,
98
+ oldestAgeMs: null,
99
+ newestEdgeAt: null,
100
+ oldestEdgeAt: null,
101
+ edgeCount: 0
102
+ };
103
+ }
104
+ const newestEdgeAt = Math.max(...timestamps);
105
+ const oldestEdgeAt = Math.min(...timestamps);
106
+ return {
107
+ newestAgeMs: Math.max(0, now - newestEdgeAt),
108
+ oldestAgeMs: Math.max(0, now - oldestEdgeAt),
109
+ newestEdgeAt,
110
+ oldestEdgeAt,
111
+ edgeCount: timestamps.length
112
+ };
113
+ }
114
+ async function computeDependentBeliefCount(ctx, beliefNodeId) {
115
+ const incomingEdges = await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", beliefNodeId)).collect();
116
+ const dependencyEdges = incomingEdges.filter(
117
+ (edge) => DEPENDENT_EDGE_TYPES.has(edge.edgeType)
118
+ );
119
+ if (dependencyEdges.length === 0) {
120
+ return 0;
121
+ }
122
+ const dependentBeliefs = await Promise.all(
123
+ dependencyEdges.map((edge) => ctx.db.get(edge.fromNodeId))
124
+ );
125
+ const uniqueBeliefIds = /* @__PURE__ */ new Set();
126
+ for (const node of dependentBeliefs) {
127
+ if (node && node.nodeType === "belief" && node.status !== "archived" && node.status !== "deleted") {
128
+ uniqueBeliefIds.add(String(node._id));
129
+ }
130
+ }
131
+ return uniqueBeliefIds.size;
132
+ }
133
+ async function snapshotEvidentialMetric(args) {
134
+ switch (args.metric) {
135
+ case "evidence_count": {
136
+ const count = await computeEvidenceCountMetric(args.ctx, args.beliefNodeId);
137
+ return {
138
+ metric: args.metric,
139
+ value: count,
140
+ data: { evidenceCount: count }
141
+ };
142
+ }
143
+ case "contradiction_status": {
144
+ const counts = await computeContradictionCounts(args.ctx, args.beliefNodeId);
145
+ return {
146
+ metric: args.metric,
147
+ value: counts.activeCount,
148
+ data: counts
149
+ };
150
+ }
151
+ case "edge_freshness": {
152
+ const freshness = await computeEvidenceFreshness(
153
+ args.ctx,
154
+ args.beliefNodeId,
155
+ args.now
156
+ );
157
+ return {
158
+ metric: args.metric,
159
+ value: freshness.newestAgeMs,
160
+ data: freshness
161
+ };
162
+ }
163
+ case "dependent_count": {
164
+ const count = await computeDependentBeliefCount(args.ctx, args.beliefNodeId);
165
+ return {
166
+ metric: args.metric,
167
+ value: count,
168
+ data: { dependentCount: count }
169
+ };
170
+ }
171
+ default:
172
+ return {
173
+ metric: args.metric,
174
+ value: null,
175
+ data: {}
176
+ };
177
+ }
178
+ }
179
+ async function evaluateBuiltInEvidentialContract(args) {
180
+ const config = parseEvidentialEvaluatorConfig(args.contract.condition.evaluatorConfig);
181
+ const snapshot = await snapshotEvidentialMetric({
182
+ ctx: args.ctx,
183
+ beliefNodeId: args.belief._id,
184
+ metric: config.metric,
185
+ now: args.now
186
+ });
187
+ const comparisonSatisfied = snapshot.value !== null && compareMetricValue(config.operator, snapshot.value, config.threshold);
188
+ const result = args.contract.direction === "falsifies" ? comparisonSatisfied ? "disconfirmed" : "confirmed" : comparisonSatisfied ? "confirmed" : "disconfirmed";
189
+ return {
190
+ result,
191
+ rationale: buildEvidentialRationale({
192
+ config,
193
+ snapshot,
194
+ comparisonSatisfied,
195
+ result
196
+ }),
197
+ data: {
198
+ ...snapshot.data,
199
+ metric: config.metric,
200
+ observedValue: snapshot.value,
201
+ operator: config.operator,
202
+ threshold: config.threshold,
203
+ action: config.action ?? "modulate_confidence",
204
+ actionParams: config.actionParams
205
+ }
206
+ };
207
+ }
208
+ async function evaluateMetricCheckerContract(args) {
209
+ const config = parseMetricCheckerConfig(args.contract.condition.evaluatorConfig);
210
+ const input = getEvaluatorInputRecord(args.inputData, "metricData");
211
+ const metric = typeof input.metric === "string" && input.metric.length > 0 ? input.metric : config.metric;
212
+ const observedValue = pickFiniteNumber(input, [
213
+ "observedValue",
214
+ "currentValue",
215
+ "metricValue",
216
+ "value"
217
+ ]) ?? config.observedValue ?? config.currentValue ?? config.metricValue ?? null;
218
+ if (observedValue === null) {
219
+ return {
220
+ result: "inconclusive",
221
+ rationale: `metric_checker is awaiting data for ${metric ?? args.contract.condition.expression}.`,
222
+ data: {
223
+ metric,
224
+ observedValue: null,
225
+ operator: config.operator,
226
+ threshold: config.threshold,
227
+ unit: config.unit
228
+ }
229
+ };
230
+ }
231
+ const comparisonSatisfied = compareMetricValue(
232
+ config.operator,
233
+ observedValue,
234
+ config.threshold
235
+ );
236
+ const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
237
+ return {
238
+ result,
239
+ rationale: buildComparisonRationale({
240
+ label: metric ?? "metric",
241
+ observedValue,
242
+ operator: config.operator,
243
+ threshold: config.threshold,
244
+ comparisonSatisfied,
245
+ result,
246
+ unit: config.unit
247
+ }),
248
+ data: {
249
+ metric,
250
+ observedValue,
251
+ operator: config.operator,
252
+ threshold: config.threshold,
253
+ unit: config.unit
254
+ }
255
+ };
256
+ }
257
+ async function evaluateReferenceCheckCounterContract(args) {
258
+ const config = parseReferenceCheckCounterConfig(args.contract.condition.evaluatorConfig);
259
+ const input = getEvaluatorInputRecord(args.inputData, "referenceCheckData");
260
+ const tag = typeof input.tag === "string" && input.tag.trim().length > 0 ? input.tag.trim() : config.tag;
261
+ const snapshot = await computeTaggedEvidenceCount({
262
+ ctx: args.ctx,
263
+ beliefNodeId: args.belief._id,
264
+ tag,
265
+ caseSensitive: config.caseSensitive
266
+ });
267
+ const comparisonSatisfied = compareMetricValue(
268
+ config.operator,
269
+ snapshot.count,
270
+ config.threshold
271
+ );
272
+ const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
273
+ return {
274
+ result,
275
+ rationale: buildComparisonRationale({
276
+ label: `reference checks tagged "${tag}"`,
277
+ observedValue: snapshot.count,
278
+ operator: config.operator,
279
+ threshold: config.threshold,
280
+ comparisonSatisfied,
281
+ result
282
+ }),
283
+ data: {
284
+ tag,
285
+ observedValue: snapshot.count,
286
+ referenceCheckCount: snapshot.count,
287
+ matchedEvidenceIds: snapshot.matchedEvidenceIds,
288
+ operator: config.operator,
289
+ threshold: config.threshold,
290
+ caseSensitive: config.caseSensitive ?? false
291
+ }
292
+ };
293
+ }
294
+ async function evaluateTemporalDeadlineContract(args) {
295
+ if (typeof args.contract.deadline !== "number" || !Number.isFinite(args.contract.deadline)) {
296
+ throw new Error(
297
+ "temporal_deadline requires contract.deadline to be set to a finite timestamp."
298
+ );
299
+ }
300
+ const config = parseTemporalDeadlineConfig(args.contract.condition.evaluatorConfig);
301
+ const input = getEvaluatorInputRecord(args.inputData, "temporalData");
302
+ const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
303
+ const completedAt = pickFiniteNumber(input, [
304
+ "completedAt",
305
+ "observedAt",
306
+ "satisfiedAt",
307
+ "achievedAt"
308
+ ]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
309
+ const completed = input.completed === true || config.completed === true || completedAt !== void 0;
310
+ if (completed) {
311
+ if (completedAt !== void 0 && completedAt > args.contract.deadline) {
312
+ return {
313
+ result: "expired",
314
+ rationale: `${label} completed at ${completedAt}, after deadline ${args.contract.deadline}.`,
315
+ data: {
316
+ label,
317
+ deadline: args.contract.deadline,
318
+ completed: true,
319
+ completedAt,
320
+ missedDeadline: true,
321
+ overdueByMs: completedAt - args.contract.deadline
322
+ }
323
+ };
324
+ }
325
+ const result = args.contract.direction === "falsifies" ? "disconfirmed" : "confirmed";
326
+ return {
327
+ result,
328
+ rationale: `${label} completed before deadline ${args.contract.deadline}.`,
329
+ data: {
330
+ label,
331
+ deadline: args.contract.deadline,
332
+ completed: true,
333
+ completedAt: completedAt ?? null,
334
+ missedDeadline: false
335
+ }
336
+ };
337
+ }
338
+ if (args.now > args.contract.deadline) {
339
+ return {
340
+ result: "expired",
341
+ rationale: `${label} missed deadline ${args.contract.deadline}; temporal contract expired.`,
342
+ data: {
343
+ label,
344
+ deadline: args.contract.deadline,
345
+ completed: false,
346
+ overdueByMs: args.now - args.contract.deadline
347
+ }
348
+ };
349
+ }
350
+ return {
351
+ result: "inconclusive",
352
+ rationale: `${label} is still before deadline ${args.contract.deadline}; awaiting outcome.`,
353
+ data: {
354
+ label,
355
+ deadline: args.contract.deadline,
356
+ completed: false,
357
+ timeRemainingMs: args.contract.deadline - args.now
358
+ }
359
+ };
360
+ }
361
+ async function evaluateMarketIndexComparatorContract(args) {
362
+ const config = parseMarketIndexComparatorConfig(args.contract.condition.evaluatorConfig);
363
+ const input = getEvaluatorInputRecord(args.inputData, "marketIndexData");
364
+ const subject = typeof input.subject === "string" && input.subject.length > 0 ? input.subject : config.subject;
365
+ const benchmark = typeof input.benchmark === "string" && input.benchmark.length > 0 ? input.benchmark : config.benchmark;
366
+ const subjectValue = pickFiniteNumber(input, ["subjectValue", "primaryValue", "leftValue"]) ?? config.subjectValue ?? config.primaryValue ?? null;
367
+ const benchmarkValue = pickFiniteNumber(input, ["benchmarkValue", "comparisonValue", "rightValue"]) ?? config.benchmarkValue ?? config.comparisonValue ?? null;
368
+ if (subjectValue === null || benchmarkValue === null) {
369
+ return {
370
+ result: "inconclusive",
371
+ rationale: "market_index_comparator is awaiting both subject and benchmark values.",
372
+ data: {
373
+ subject,
374
+ subjectValue,
375
+ benchmark,
376
+ benchmarkValue,
377
+ operator: config.operator,
378
+ threshold: config.threshold
379
+ }
380
+ };
381
+ }
382
+ if (benchmarkValue === 0) {
383
+ throw new Error(
384
+ "market_index_comparator cannot compare against a zero benchmark value."
385
+ );
386
+ }
387
+ const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
388
+ const comparisonSatisfied = compareMetricValue(
389
+ config.operator,
390
+ differentialPercent,
391
+ config.threshold
392
+ );
393
+ const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
394
+ return {
395
+ result,
396
+ rationale: buildComparisonRationale({
397
+ label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
398
+ observedValue: differentialPercent,
399
+ operator: config.operator,
400
+ threshold: config.threshold,
401
+ comparisonSatisfied,
402
+ result,
403
+ unit: "%"
404
+ }),
405
+ data: {
406
+ subject,
407
+ subjectValue,
408
+ benchmark,
409
+ benchmarkValue,
410
+ differentialPercent,
411
+ operator: config.operator,
412
+ threshold: config.threshold
413
+ }
414
+ };
415
+ }
416
+ var METRIC_COMPARATOR_EVALUATOR_NAMES = {
417
+ evidential: "evidential",
418
+ evidentialAliases: /* @__PURE__ */ new Set(["evidential", "built_in_evidential", "builtin_evidential"]),
419
+ metricChecker: "metric_checker",
420
+ referenceCheckCounter: "reference_check_counter",
421
+ temporalDeadline: "temporal_deadline",
422
+ marketIndexComparator: "market_index_comparator"
423
+ };
424
+
425
+ export { METRIC_COMPARATOR_EVALUATOR_NAMES, computeContradictionCounts, computeDependentBeliefCount, computeEvidenceCountMetric, computeEvidenceFreshness, evaluateBuiltInEvidentialContract, evaluateMarketIndexComparatorContract, evaluateMetricCheckerContract, evaluateReferenceCheckCounterContract, evaluateTemporalDeadlineContract };
426
+ //# sourceMappingURL=epistemicContracts.metrics.js.map
427
+ //# sourceMappingURL=epistemicContracts.metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/epistemicContracts.metrics.ts"],"names":[],"mappings":";;;;;AAoCA,IAAM,6BAAA,uBAAoC,GAAA,CAAI;AAAA,EAC5C,YAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,IAAM,oBAAA,uBAA2B,GAAA,CAAI;AAAA,EACnC;AACF,CAAC,CAAA;AAED,SAAS,4BAA4B,MAAA,EAAwC;AAC3E,EAAA,IAAI,OAAO,WAAW,QAAA,EAAU;AAC9B,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,IAAI,6BAAA,CAA8B,GAAA,CAAI,MAAM,CAAA,EAAG;AAC7C,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,IACE,MAAA,KAAW,kBAAA,IACX,MAAA,KAAW,iBAAA,IACX,WAAW,eAAA,EACX;AACA,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,OAAO,UAAA;AACT;AAEA,SAAS,iBAAiB,IAAA,EAIR;AAChB,EAAA,IAAI,OAAO,IAAA,CAAK,SAAA,KAAc,QAAA,EAAU;AACtC,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AACA,EAAA,IAAI,OAAO,IAAA,CAAK,SAAA,KAAc,QAAA,EAAU;AACtC,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AACA,EAAA,IAAI,OAAO,IAAA,CAAK,aAAA,KAAkB,QAAA,EAAU;AAC1C,IAAA,OAAO,IAAA,CAAK,aAAA;AAAA,EACd;AACA,EAAA,OAAO,IAAA;AACT;AAEA,eAAe,gBAAA,CACb,KACA,YAAA,EACkE;AAClE,EAAA,MAAM,QAAQ,MAAO,GAAA,CAAI,EAAA,CACtB,KAAA,CAAM,gBAAgB,CAAA,CACtB,SAAA;AAAA,IAAU,YAAA;AAAA,IAAc,CAAC,MACxB,CAAA,CAAE,EAAA,CAAG,YAAY,YAAY,CAAA,CAAE,EAAA,CAAG,UAAA,EAAY,SAAS;AAAA,IAExD,OAAA,EAAQ;AAEX,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAM,GAAA,CAAI,CAAC,IAAA,KAAS,GAAA,CAAI,EAAA,CAAG,GAAA,CAAI,IAAA,CAAK,UAAU,CAAC,CAAC,CAAA;AAChF,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,EAAM,KAAA,KAAU;AACpC,IAAA,MAAM,IAAA,GAAO,MAAM,KAAK,CAAA;AACxB,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,aAAa,UAAA,IAAc,IAAA,CAAK,WAAW,UAAA,EAAY;AACvE,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,OAAO,CAAC,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,EACxB,CAAC,CAAA;AACH;AAEA,SAAS,gBAAgB,IAAA,EAAiC;AACxD,EAAA,MAAM,QAAA,GACJ,KAAK,QAAA,IAAY,OAAO,KAAK,QAAA,KAAa,QAAA,GACrC,KAAK,QAAA,GACN,IAAA;AACN,EAAA,MAAM,OAAO,QAAA,EAAU,IAAA;AACvB,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACxB,IAAA,OAAO,EAAC;AAAA,EACV;AACA,EAAA,OAAO,KAAK,MAAA,CAAO,CAAC,GAAA,KAAuB,OAAO,QAAQ,QAAQ,CAAA;AACpE;AAEA,eAAsB,0BAAA,CACpB,KACA,YAAA,EACiB;AACjB,EAAA,OAAA,CAAQ,MAAM,gBAAA,CAAiB,GAAA,EAAK,YAAY,CAAA,EAAG,MAAA;AACrD;AAEA,eAAe,2BAA2B,IAAA,EAKmB;AAC3D,EAAA,MAAM,cAAc,IAAA,CAAK,aAAA,GAAgB,KAAK,GAAA,GAAM,IAAA,CAAK,IAAI,WAAA,EAAY;AACzE,EAAA,MAAM,sBAAsB,MAAM,gBAAA,CAAiB,KAAK,GAAA,EAAK,IAAA,CAAK,YAAY,CAAA,EAC3E,MAAA;AAAA,IAAO,CAAC,EAAE,IAAA,EAAK,KACd,eAAA,CAAgB,IAAI,CAAA,CAAE,IAAA;AAAA,MAAK,CAAC,GAAA,KAAA,CACzB,IAAA,CAAK,gBAAgB,GAAA,GAAM,GAAA,CAAI,aAAY,MAAO;AAAA;AACrD,GACF,CACC,IAAI,CAAC,EAAE,MAAK,KAAM,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA;AAErC,EAAA,OAAO;AAAA,IACL,OAAO,kBAAA,CAAmB,MAAA;AAAA,IAC1B;AAAA,GACF;AACF;AAEA,eAAsB,0BAAA,CACpB,KACA,YAAA,EACoC;AACpC,EAAA,MAAM,iBAAiB,MAAQ,GAAA,CAAI,EAAA,CAChC,KAAA,CAAM,gBAAgB,CAAA,CACtB,SAAA,CAAU,aAAA,EAAe,CAAC,MAAW,CAAA,CAAE,EAAA,CAAG,YAAY,YAAY,CAAC,EACnE,OAAA,EAAQ;AAIX,EAAA,OAAO,cAAA,CAAe,MAAA;AAAA,IACpB,CAAC,QAAQ,aAAA,KAAkB;AACzB,MAAA,MAAM,MAAA,GACJ,aAAA,CAAc,gBAAA,IAAoB,aAAA,CAAc,MAAA,IAAU,YAAA;AAC5D,MAAA,IAAI,2BAAA,CAA4B,MAAM,CAAA,KAAM,QAAA,EAAU;AACpD,QAAA,MAAA,CAAO,WAAA,IAAe,CAAA;AAAA,MACxB,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,aAAA,IAAiB,CAAA;AAAA,MAC1B;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,EAAE,WAAA,EAAa,CAAA,EAAG,aAAA,EAAe,CAAA;AAAE,GACrC;AACF;AAEA,eAAsB,yBACpB,GAAA,EACA,YAAA,EACA,GAAA,GAAM,IAAA,CAAK,KAAI,EACa;AAC5B,EAAA,MAAM,cAAc,MAAM,gBAAA,CAAiB,KAAK,YAAY,CAAA,EACzD,IAAI,CAAC,EAAE,MAAK,KAAM,gBAAA,CAAiB,IAAI,CAAC,CAAA,CACxC,OAAO,CAAC,KAAA,KAA2B,UAAU,IAAI,CAAA;AAEpD,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,IAAA;AAAA,MACb,WAAA,EAAa,IAAA;AAAA,MACb,YAAA,EAAc,IAAA;AAAA,MACd,YAAA,EAAc,IAAA;AAAA,MACd,SAAA,EAAW;AAAA,KACb;AAAA,EACF;AAEA,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,GAAG,UAAU,CAAA;AAC3C,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,GAAG,UAAU,CAAA;AAE3C,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,YAAY,CAAA;AAAA,IAC3C,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,YAAY,CAAA;AAAA,IAC3C,YAAA;AAAA,IACA,YAAA;AAAA,IACA,WAAW,UAAA,CAAW;AAAA,GACxB;AACF;AAEA,eAAsB,2BAAA,CACpB,KACA,YAAA,EACiB;AACjB,EAAA,MAAM,gBAAgB,MAAO,GAAA,CAAI,EAAA,CAC9B,KAAA,CAAM,gBAAgB,CAAA,CACtB,SAAA,CAAU,OAAA,EAAS,CAAC,MAAM,CAAA,CAAE,EAAA,CAAG,YAAY,YAAY,CAAC,EACxD,OAAA,EAAQ;AAIX,EAAA,MAAM,kBAAkB,aAAA,CAAc,MAAA;AAAA,IAAO,CAAC,IAAA,KAC5C,oBAAA,CAAqB,GAAA,CAAI,KAAK,QAAQ;AAAA,GACxC;AACA,EAAA,IAAI,eAAA,CAAgB,WAAW,CAAA,EAAG;AAChC,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,gBAAA,GAAmB,MAAM,OAAA,CAAQ,GAAA;AAAA,IACrC,eAAA,CAAgB,IAAI,CAAC,IAAA,KAAS,IAAI,EAAA,CAAG,GAAA,CAAI,IAAA,CAAK,UAAU,CAAC;AAAA,GAC3D;AACA,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAY;AAExC,EAAA,KAAA,MAAW,QAAQ,gBAAA,EAAkB;AACnC,IAAA,IACE,IAAA,IACA,KAAK,QAAA,KAAa,QAAA,IAClB,KAAK,MAAA,KAAW,UAAA,IAChB,IAAA,CAAK,MAAA,KAAW,SAAA,EAChB;AACA,MAAA,eAAA,CAAgB,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,OAAO,eAAA,CAAgB,IAAA;AACzB;AAEA,eAAe,yBAAyB,IAAA,EAKF;AACpC,EAAA,QAAQ,KAAK,MAAA;AAAQ,IACnB,KAAK,gBAAA,EAAkB;AACrB,MAAA,MAAM,QAAQ,MAAM,0BAAA,CAA2B,IAAA,CAAK,GAAA,EAAK,KAAK,YAAY,CAAA;AAC1E,MAAA,OAAO;AAAA,QACL,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,KAAA,EAAO,KAAA;AAAA,QACP,IAAA,EAAM,EAAE,aAAA,EAAe,KAAA;AAAM,OAC/B;AAAA,IACF;AAAA,IACA,KAAK,sBAAA,EAAwB;AAC3B,MAAA,MAAM,SAAS,MAAM,0BAAA,CAA2B,IAAA,CAAK,GAAA,EAAK,KAAK,YAAY,CAAA;AAC3E,MAAA,OAAO;AAAA,QACL,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,OAAO,MAAA,CAAO,WAAA;AAAA,QACd,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAAA,IACA,KAAK,gBAAA,EAAkB;AACrB,MAAA,MAAM,YAAY,MAAM,wBAAA;AAAA,QACtB,IAAA,CAAK,GAAA;AAAA,QACL,IAAA,CAAK,YAAA;AAAA,QACL,IAAA,CAAK;AAAA,OACP;AACA,MAAA,OAAO;AAAA,QACL,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,OAAO,SAAA,CAAU,WAAA;AAAA,QACjB,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAAA,IACA,KAAK,iBAAA,EAAmB;AACtB,MAAA,MAAM,QAAQ,MAAM,2BAAA,CAA4B,IAAA,CAAK,GAAA,EAAK,KAAK,YAAY,CAAA;AAC3E,MAAA,OAAO;AAAA,QACL,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,KAAA,EAAO,KAAA;AAAA,QACP,IAAA,EAAM,EAAE,cAAA,EAAgB,KAAA;AAAM,OAChC;AAAA,IACF;AAAA,IACA;AACE,MAAA,OAAO;AAAA,QACL,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,KAAA,EAAO,IAAA;AAAA,QACP,MAAM;AAAC,OACT;AAAA;AAEN;AAEA,eAAsB,kCACpB,IAAA,EACmC;AACnC,EAAA,MAAM,MAAA,GAAS,8BAAA,CAA+B,IAAA,CAAK,QAAA,CAAS,UAAU,eAAe,CAAA;AACrF,EAAA,MAAM,QAAA,GAAW,MAAM,wBAAA,CAAyB;AAAA,IAC9C,KAAK,IAAA,CAAK,GAAA;AAAA,IACV,YAAA,EAAc,KAAK,MAAA,CAAO,GAAA;AAAA,IAC1B,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,KAAK,IAAA,CAAK;AAAA,GACX,CAAA;AAED,EAAA,MAAM,mBAAA,GACJ,QAAA,CAAS,KAAA,KAAU,IAAA,IACnB,kBAAA,CAAmB,OAAO,QAAA,EAAU,QAAA,CAAS,KAAA,EAAO,MAAA,CAAO,SAAS,CAAA;AACtE,EAAA,MAAM,MAAA,GACJ,KAAK,QAAA,CAAS,SAAA,KAAc,cACxB,mBAAA,GACE,cAAA,GACA,WAAA,GACF,mBAAA,GACE,WAAA,GACA,cAAA;AAER,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,WAAW,wBAAA,CAAyB;AAAA,MAClC,MAAA;AAAA,MACA,QAAA;AAAA,MACA,mBAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,IACD,IAAA,EAAM;AAAA,MACJ,GAAG,QAAA,CAAS,IAAA;AAAA,MACZ,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,eAAe,QAAA,CAAS,KAAA;AAAA,MACxB,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,MAAA,EAAQ,OAAO,MAAA,IAAU,qBAAA;AAAA,MACzB,cAAc,MAAA,CAAO;AAAA;AACvB,GACF;AACF;AAEA,eAAsB,8BACpB,IAAA,EACmC;AACnC,EAAA,MAAM,MAAA,GAAS,wBAAA,CAAyB,IAAA,CAAK,QAAA,CAAS,UAAU,eAAe,CAAA;AAC/E,EAAA,MAAM,KAAA,GAAQ,uBAAA,CAAwB,IAAA,CAAK,SAAA,EAAW,YAAY,CAAA;AAClE,EAAA,MAAM,MAAA,GACJ,OAAO,KAAA,CAAM,MAAA,KAAW,QAAA,IAAY,KAAA,CAAM,MAAA,CAAO,MAAA,GAAS,CAAA,GACtD,KAAA,CAAM,MAAA,GACN,MAAA,CAAO,MAAA;AACb,EAAA,MAAM,aAAA,GACJ,iBAAiB,KAAA,EAAO;AAAA,IACtB,eAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA,IACD,MAAA,CAAO,iBACP,MAAA,CAAO,YAAA,IACP,OAAO,WAAA,IACP,IAAA;AACF,EAAA,IAAI,kBAAkB,IAAA,EAAM;AAC1B,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,cAAA;AAAA,MACR,WAAW,CAAA,oCAAA,EAAuC,MAAA,IAAU,IAAA,CAAK,QAAA,CAAS,UAAU,UAAU,CAAA,CAAA,CAAA;AAAA,MAC9F,IAAA,EAAM;AAAA,QACJ,MAAA;AAAA,QACA,aAAA,EAAe,IAAA;AAAA,QACf,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,MAAM,MAAA,CAAO;AAAA;AACf,KACF;AAAA,EACF;AAEA,EAAA,MAAM,mBAAA,GAAsB,kBAAA;AAAA,IAC1B,MAAA,CAAO,QAAA;AAAA,IACP,aAAA;AAAA,IACA,MAAA,CAAO;AAAA,GACT;AACA,EAAA,MAAM,MAAA,GAAS,uBAAA,CAAwB,IAAA,CAAK,QAAA,CAAS,WAAW,mBAAmB,CAAA;AAEnF,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,WAAW,wBAAA,CAAyB;AAAA,MAClC,OAAO,MAAA,IAAU,QAAA;AAAA,MACjB,aAAA;AAAA,MACA,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,mBAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAM,MAAA,CAAO;AAAA,KACd,CAAA;AAAA,IACD,IAAA,EAAM;AAAA,MACJ,MAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,MAAM,MAAA,CAAO;AAAA;AACf,GACF;AACF;AAEA,eAAsB,sCACpB,IAAA,EACmC;AACnC,EAAA,MAAM,MAAA,GAAS,gCAAA,CAAiC,IAAA,CAAK,QAAA,CAAS,UAAU,eAAe,CAAA;AACvF,EAAA,MAAM,KAAA,GAAQ,uBAAA,CAAwB,IAAA,CAAK,SAAA,EAAW,oBAAoB,CAAA;AAC1E,EAAA,MAAM,GAAA,GACJ,OAAO,KAAA,CAAM,GAAA,KAAQ,YAAY,KAAA,CAAM,GAAA,CAAI,IAAA,EAAK,CAAE,SAAS,CAAA,GACvD,KAAA,CAAM,GAAA,CAAI,IAAA,KACV,MAAA,CAAO,GAAA;AACb,EAAA,MAAM,QAAA,GAAW,MAAM,0BAAA,CAA2B;AAAA,IAChD,KAAK,IAAA,CAAK,GAAA;AAAA,IACV,YAAA,EAAc,KAAK,MAAA,CAAO,GAAA;AAAA,IAC1B,GAAA;AAAA,IACA,eAAe,MAAA,CAAO;AAAA,GACvB,CAAA;AACD,EAAA,MAAM,mBAAA,GAAsB,kBAAA;AAAA,IAC1B,MAAA,CAAO,QAAA;AAAA,IACP,QAAA,CAAS,KAAA;AAAA,IACT,MAAA,CAAO;AAAA,GACT;AACA,EAAA,MAAM,MAAA,GAAS,uBAAA,CAAwB,IAAA,CAAK,QAAA,CAAS,WAAW,mBAAmB,CAAA;AAEnF,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,WAAW,wBAAA,CAAyB;AAAA,MAClC,KAAA,EAAO,4BAA4B,GAAG,CAAA,CAAA,CAAA;AAAA,MACtC,eAAe,QAAA,CAAS,KAAA;AAAA,MACxB,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,mBAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,IACD,IAAA,EAAM;AAAA,MACJ,GAAA;AAAA,MACA,eAAe,QAAA,CAAS,KAAA;AAAA,MACxB,qBAAqB,QAAA,CAAS,KAAA;AAAA,MAC9B,oBAAoB,QAAA,CAAS,kBAAA;AAAA,MAC7B,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,aAAA,EAAe,OAAO,aAAA,IAAiB;AAAA;AACzC,GACF;AACF;AAEA,eAAsB,iCACpB,IAAA,EACmC;AACnC,EAAA,IACE,OAAO,IAAA,CAAK,QAAA,CAAS,QAAA,KAAa,QAAA,IAClC,CAAC,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EACvC;AACA,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,2BAAA,CAA4B,IAAA,CAAK,QAAA,CAAS,UAAU,eAAe,CAAA;AAClF,EAAA,MAAM,KAAA,GAAQ,uBAAA,CAAwB,IAAA,CAAK,SAAA,EAAW,cAAc,CAAA;AACpE,EAAA,MAAM,SACH,OAAO,KAAA,CAAM,UAAU,QAAA,IAAY,KAAA,CAAM,MAAM,MAAA,GAAS,CAAA,GACrD,KAAA,CAAM,KAAA,GACN,OAAO,KAAA,KACX,IAAA,CAAK,SAAS,KAAA,IACd,IAAA,CAAK,SAAS,SAAA,CAAU,UAAA;AAC1B,EAAA,MAAM,WAAA,GACJ,iBAAiB,KAAA,EAAO;AAAA,IACtB,aAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,KACD,MAAA,CAAO,WAAA,IACP,OAAO,UAAA,IACP,MAAA,CAAO,eACP,MAAA,CAAO,UAAA;AACT,EAAA,MAAM,YACJ,KAAA,CAAM,SAAA,KAAc,QAAQ,MAAA,CAAO,SAAA,KAAc,QAAQ,WAAA,KAAgB,MAAA;AAE3E,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,IAAI,WAAA,KAAgB,MAAA,IAAa,WAAA,GAAc,IAAA,CAAK,SAAS,QAAA,EAAU;AACrE,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,SAAA;AAAA,QACR,SAAA,EAAW,GAAG,KAAK,CAAA,cAAA,EAAiB,WAAW,CAAA,iBAAA,EAAoB,IAAA,CAAK,SAAS,QAAQ,CAAA,CAAA,CAAA;AAAA,QACzF,IAAA,EAAM;AAAA,UACJ,KAAA;AAAA,UACA,QAAA,EAAU,KAAK,QAAA,CAAS,QAAA;AAAA,UACxB,SAAA,EAAW,IAAA;AAAA,UACX,WAAA;AAAA,UACA,cAAA,EAAgB,IAAA;AAAA,UAChB,WAAA,EAAa,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS;AAAA;AAC3C,OACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GACJ,IAAA,CAAK,QAAA,CAAS,SAAA,KAAc,cAAc,cAAA,GAAiB,WAAA;AAC7D,IAAA,OAAO;AAAA,MACL,MAAA;AAAA,MACA,WAAW,CAAA,EAAG,KAAK,CAAA,2BAAA,EAA8B,IAAA,CAAK,SAAS,QAAQ,CAAA,CAAA,CAAA;AAAA,MACvE,IAAA,EAAM;AAAA,QACJ,KAAA;AAAA,QACA,QAAA,EAAU,KAAK,QAAA,CAAS,QAAA;AAAA,QACxB,SAAA,EAAW,IAAA;AAAA,QACX,aAAa,WAAA,IAAe,IAAA;AAAA,QAC5B,cAAA,EAAgB;AAAA;AAClB,KACF;AAAA,EACF;AAEA,EAAA,IAAI,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,QAAA,EAAU;AACrC,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,SAAA;AAAA,MACR,WAAW,CAAA,EAAG,KAAK,CAAA,iBAAA,EAAoB,IAAA,CAAK,SAAS,QAAQ,CAAA,4BAAA,CAAA;AAAA,MAC7D,IAAA,EAAM;AAAA,QACJ,KAAA;AAAA,QACA,QAAA,EAAU,KAAK,QAAA,CAAS,QAAA;AAAA,QACxB,SAAA,EAAW,KAAA;AAAA,QACX,WAAA,EAAa,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS;AAAA;AACxC,KACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,cAAA;AAAA,IACR,WAAW,CAAA,EAAG,KAAK,CAAA,0BAAA,EAA6B,IAAA,CAAK,SAAS,QAAQ,CAAA,mBAAA,CAAA;AAAA,IACtE,IAAA,EAAM;AAAA,MACJ,KAAA;AAAA,MACA,QAAA,EAAU,KAAK,QAAA,CAAS,QAAA;AAAA,MACxB,SAAA,EAAW,KAAA;AAAA,MACX,eAAA,EAAiB,IAAA,CAAK,QAAA,CAAS,QAAA,GAAW,IAAA,CAAK;AAAA;AACjD,GACF;AACF;AAEA,eAAsB,sCACpB,IAAA,EACmC;AACnC,EAAA,MAAM,MAAA,GAAS,gCAAA,CAAiC,IAAA,CAAK,QAAA,CAAS,UAAU,eAAe,CAAA;AACvF,EAAA,MAAM,KAAA,GAAQ,uBAAA,CAAwB,IAAA,CAAK,SAAA,EAAW,iBAAiB,CAAA;AACvE,EAAA,MAAM,OAAA,GACJ,OAAO,KAAA,CAAM,OAAA,KAAY,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,MAAA,GAAS,CAAA,GACxD,KAAA,CAAM,OAAA,GACN,MAAA,CAAO,OAAA;AACb,EAAA,MAAM,SAAA,GACJ,OAAO,KAAA,CAAM,SAAA,KAAc,QAAA,IAAY,KAAA,CAAM,SAAA,CAAU,MAAA,GAAS,CAAA,GAC5D,KAAA,CAAM,SAAA,GACN,MAAA,CAAO,SAAA;AACb,EAAA,MAAM,YAAA,GACJ,gBAAA,CAAiB,KAAA,EAAO,CAAC,cAAA,EAAgB,cAAA,EAAgB,WAAW,CAAC,CAAA,IACrE,MAAA,CAAO,YAAA,IACP,MAAA,CAAO,YAAA,IACP,IAAA;AACF,EAAA,MAAM,cAAA,GACJ,gBAAA,CAAiB,KAAA,EAAO,CAAC,gBAAA,EAAkB,iBAAA,EAAmB,YAAY,CAAC,CAAA,IAC3E,MAAA,CAAO,cAAA,IACP,MAAA,CAAO,eAAA,IACP,IAAA;AAEF,EAAA,IAAI,YAAA,KAAiB,IAAA,IAAQ,cAAA,KAAmB,IAAA,EAAM;AACpD,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,cAAA;AAAA,MACR,SAAA,EAAW,wEAAA;AAAA,MACX,IAAA,EAAM;AAAA,QACJ,OAAA;AAAA,QACA,YAAA;AAAA,QACA,SAAA;AAAA,QACA,cAAA;AAAA,QACA,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,WAAW,MAAA,CAAO;AAAA;AACpB,KACF;AAAA,EACF;AAEA,EAAA,IAAI,mBAAmB,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,uBACF,YAAA,GAAe,cAAA,IAAkB,IAAA,CAAK,GAAA,CAAI,cAAc,CAAA,GAAK,GAAA;AACjE,EAAA,MAAM,mBAAA,GAAsB,kBAAA;AAAA,IAC1B,MAAA,CAAO,QAAA;AAAA,IACP,mBAAA;AAAA,IACA,MAAA,CAAO;AAAA,GACT;AACA,EAAA,MAAM,MAAA,GAAS,uBAAA,CAAwB,IAAA,CAAK,QAAA,CAAS,WAAW,mBAAmB,CAAA;AAEnF,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,WAAW,wBAAA,CAAyB;AAAA,MAClC,OAAO,CAAA,EAAG,OAAA,IAAW,SAAS,CAAA,IAAA,EAAO,aAAa,WAAW,CAAA,aAAA,CAAA;AAAA,MAC7D,aAAA,EAAe,mBAAA;AAAA,MACf,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,mBAAA;AAAA,MACA,MAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,IACD,IAAA,EAAM;AAAA,MACJ,OAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA;AAAA,MACA,cAAA;AAAA,MACA,mBAAA;AAAA,MACA,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,MAAA,CAAO;AAAA;AACpB,GACF;AACF;AAEO,IAAM,iCAAA,GAAoC;AAAA,EAC/C,UAAA,EAAY,YAAA;AAAA,EACZ,mCAAmB,IAAI,GAAA,CAAI,CAAC,YAAA,EAAc,qBAAA,EAAuB,oBAAoB,CAAC,CAAA;AAAA,EACtF,aAAA,EAAe,gBAAA;AAAA,EACf,qBAAA,EAAuB,yBAAA;AAAA,EACvB,gBAAA,EAAkB,mBAAA;AAAA,EAClB,qBAAA,EAAuB;AACzB","file":"epistemicContracts.metrics.js","sourcesContent":["/** Metric helpers and evidential snapshots used by contract evaluators. */\n\nimport type { Id } from \"./convex\";\nimport {\n buildEvidentialRationale,\n buildComparisonRationale,\n compareMetricValue,\n parseMetricCheckerConfig,\n parseReferenceCheckCounterConfig,\n parseTemporalDeadlineConfig,\n parseMarketIndexComparatorConfig,\n parseEvidentialEvaluatorConfig,\n pickFiniteNumber,\n resolveComparisonResult,\n getEvaluatorInputRecord,\n} from \"./epistemicContractHelpers\";\nimport {\n type ContractDoc,\n type ContractReadCtx,\n type ContradictionStatusCounts,\n type EvidenceEdgeDoc,\n type EvidenceFreshness,\n type EvidenceNodeDoc,\n type EvidentialAction,\n type EvidentialEvaluatorConfig,\n type EvidentialMetric,\n type EvidentialMetricSnapshot,\n type EpistemicEvaluator,\n type EpistemicEvaluatorContext,\n type EpistemicEvaluatorResult,\n type MarketIndexComparatorConfig,\n type MetricCheckerEvaluatorConfig,\n type ReferenceCheckCounterConfig,\n type TemporalDeadlineEvaluatorConfig,\n} from \"./epistemicContracts.types\";\n\nconst ACTIVE_CONTRADICTION_STATUSES = new Set([\n \"unresolved\",\n \"investigating\",\n \"accepted_as_permanent\",\n]);\n\nconst DEPENDENT_EDGE_TYPES = new Set([\n \"depends_on\",\n]);\n\nfunction classifyContradictionStatus(status: unknown): \"active\" | \"resolved\" {\n if (typeof status !== \"string\") {\n return \"active\";\n }\n\n if (ACTIVE_CONTRADICTION_STATUSES.has(status)) {\n return \"active\";\n }\n\n if (\n status === \"resolved_support\" ||\n status === \"resolved_contra\" ||\n status === \"belief_forked\"\n ) {\n return \"resolved\";\n }\n\n return \"resolved\";\n}\n\nfunction getEdgeTimestamp(edge: {\n updatedAt?: unknown;\n createdAt?: unknown;\n _creationTime?: unknown;\n}): number | null {\n if (typeof edge.updatedAt === \"number\") {\n return edge.updatedAt;\n }\n if (typeof edge.createdAt === \"number\") {\n return edge.createdAt;\n }\n if (typeof edge._creationTime === \"number\") {\n return edge._creationTime;\n }\n return null;\n}\n\nasync function getEvidenceLinks(\n ctx: ContractReadCtx,\n beliefNodeId: Id<\"epistemicNodes\">\n): Promise<Array<{ edge: EvidenceEdgeDoc; node: EvidenceNodeDoc }>> {\n const edges = await (ctx.db\n .query(\"epistemicEdges\")\n .withIndex(\"by_to_type\", (q) =>\n q.eq(\"toNodeId\", beliefNodeId).eq(\"edgeType\", \"informs\")\n )\n .collect() as Promise<EvidenceEdgeDoc[]>);\n\n if (edges.length === 0) {\n return [];\n }\n\n const nodes = await Promise.all(edges.map((edge) => ctx.db.get(edge.fromNodeId)));\n return edges.flatMap((edge, index) => {\n const node = nodes[index] as EvidenceNodeDoc | null;\n if (!node || node.nodeType !== \"evidence\" || node.status === \"archived\") {\n return [];\n }\n return [{ edge, node }];\n });\n}\n\nfunction getEvidenceTags(node: EvidenceNodeDoc): string[] {\n const metadata =\n node.metadata && typeof node.metadata === \"object\"\n ? (node.metadata as Record<string, unknown>)\n : null;\n const tags = metadata?.tags;\n if (!Array.isArray(tags)) {\n return [];\n }\n return tags.filter((tag): tag is string => typeof tag === \"string\");\n}\n\nexport async function computeEvidenceCountMetric(\n ctx: ContractReadCtx,\n beliefNodeId: Id<\"epistemicNodes\">\n): Promise<number> {\n return (await getEvidenceLinks(ctx, beliefNodeId)).length;\n}\n\nasync function computeTaggedEvidenceCount(args: {\n ctx: ContractReadCtx;\n beliefNodeId: Id<\"epistemicNodes\">;\n tag: string;\n caseSensitive?: boolean;\n}): Promise<{ count: number; matchedEvidenceIds: string[] }> {\n const expectedTag = args.caseSensitive ? args.tag : args.tag.toLowerCase();\n const matchedEvidenceIds = (await getEvidenceLinks(args.ctx, args.beliefNodeId))\n .filter(({ node }) =>\n getEvidenceTags(node).some((tag) =>\n (args.caseSensitive ? tag : tag.toLowerCase()) === expectedTag\n )\n )\n .map(({ node }) => String(node._id));\n\n return {\n count: matchedEvidenceIds.length,\n matchedEvidenceIds,\n };\n}\n\nexport async function computeContradictionCounts(\n ctx: ContractReadCtx,\n beliefNodeId: Id<\"epistemicNodes\">\n): Promise<ContradictionStatusCounts> {\n const contradictions = await ((ctx.db as any)\n .query(\"contradictions\")\n .withIndex(\"by_beliefId\", (q: any) => q.eq(\"beliefId\", beliefNodeId))\n .collect() as Promise<\n Array<{ resolutionStatus?: string; status?: string }>\n >);\n\n return contradictions.reduce<ContradictionStatusCounts>(\n (counts, contradiction) => {\n const status =\n contradiction.resolutionStatus ?? contradiction.status ?? \"unresolved\";\n if (classifyContradictionStatus(status) === \"active\") {\n counts.activeCount += 1;\n } else {\n counts.resolvedCount += 1;\n }\n return counts;\n },\n { activeCount: 0, resolvedCount: 0 }\n );\n}\n\nexport async function computeEvidenceFreshness(\n ctx: ContractReadCtx,\n beliefNodeId: Id<\"epistemicNodes\">,\n now = Date.now()\n): Promise<EvidenceFreshness> {\n const timestamps = (await getEvidenceLinks(ctx, beliefNodeId))\n .map(({ edge }) => getEdgeTimestamp(edge))\n .filter((value): value is number => value !== null);\n\n if (timestamps.length === 0) {\n return {\n newestAgeMs: null,\n oldestAgeMs: null,\n newestEdgeAt: null,\n oldestEdgeAt: null,\n edgeCount: 0,\n };\n }\n\n const newestEdgeAt = Math.max(...timestamps);\n const oldestEdgeAt = Math.min(...timestamps);\n\n return {\n newestAgeMs: Math.max(0, now - newestEdgeAt),\n oldestAgeMs: Math.max(0, now - oldestEdgeAt),\n newestEdgeAt,\n oldestEdgeAt,\n edgeCount: timestamps.length,\n };\n}\n\nexport async function computeDependentBeliefCount(\n ctx: ContractReadCtx,\n beliefNodeId: Id<\"epistemicNodes\">\n): Promise<number> {\n const incomingEdges = await (ctx.db\n .query(\"epistemicEdges\")\n .withIndex(\"by_to\", (q) => q.eq(\"toNodeId\", beliefNodeId))\n .collect() as Promise<\n Array<{ fromNodeId: Id<\"epistemicNodes\">; edgeType: string }>\n >);\n\n const dependencyEdges = incomingEdges.filter((edge) =>\n DEPENDENT_EDGE_TYPES.has(edge.edgeType)\n );\n if (dependencyEdges.length === 0) {\n return 0;\n }\n\n const dependentBeliefs = await Promise.all(\n dependencyEdges.map((edge) => ctx.db.get(edge.fromNodeId))\n );\n const uniqueBeliefIds = new Set<string>();\n\n for (const node of dependentBeliefs) {\n if (\n node &&\n node.nodeType === \"belief\" &&\n node.status !== \"archived\" &&\n node.status !== \"deleted\"\n ) {\n uniqueBeliefIds.add(String(node._id));\n }\n }\n\n return uniqueBeliefIds.size;\n}\n\nasync function snapshotEvidentialMetric(args: {\n ctx: ContractReadCtx;\n beliefNodeId: Id<\"epistemicNodes\">;\n metric: EvidentialMetric;\n now: number;\n}): Promise<EvidentialMetricSnapshot> {\n switch (args.metric) {\n case \"evidence_count\": {\n const count = await computeEvidenceCountMetric(args.ctx, args.beliefNodeId);\n return {\n metric: args.metric,\n value: count,\n data: { evidenceCount: count },\n };\n }\n case \"contradiction_status\": {\n const counts = await computeContradictionCounts(args.ctx, args.beliefNodeId);\n return {\n metric: args.metric,\n value: counts.activeCount,\n data: counts,\n };\n }\n case \"edge_freshness\": {\n const freshness = await computeEvidenceFreshness(\n args.ctx,\n args.beliefNodeId,\n args.now\n );\n return {\n metric: args.metric,\n value: freshness.newestAgeMs,\n data: freshness,\n };\n }\n case \"dependent_count\": {\n const count = await computeDependentBeliefCount(args.ctx, args.beliefNodeId);\n return {\n metric: args.metric,\n value: count,\n data: { dependentCount: count },\n };\n }\n default:\n return {\n metric: args.metric,\n value: null,\n data: {},\n };\n }\n}\n\nexport async function evaluateBuiltInEvidentialContract(\n args: EpistemicEvaluatorContext\n): Promise<EpistemicEvaluatorResult> {\n const config = parseEvidentialEvaluatorConfig(args.contract.condition.evaluatorConfig);\n const snapshot = await snapshotEvidentialMetric({\n ctx: args.ctx,\n beliefNodeId: args.belief._id,\n metric: config.metric,\n now: args.now,\n });\n\n const comparisonSatisfied =\n snapshot.value !== null &&\n compareMetricValue(config.operator, snapshot.value, config.threshold);\n const result =\n args.contract.direction === \"falsifies\"\n ? comparisonSatisfied\n ? \"disconfirmed\"\n : \"confirmed\"\n : comparisonSatisfied\n ? \"confirmed\"\n : \"disconfirmed\";\n\n return {\n result,\n rationale: buildEvidentialRationale({\n config,\n snapshot,\n comparisonSatisfied,\n result,\n }),\n data: {\n ...snapshot.data,\n metric: config.metric,\n observedValue: snapshot.value,\n operator: config.operator,\n threshold: config.threshold,\n action: config.action ?? \"modulate_confidence\",\n actionParams: config.actionParams,\n },\n };\n}\n\nexport async function evaluateMetricCheckerContract(\n args: EpistemicEvaluatorContext\n): Promise<EpistemicEvaluatorResult> {\n const config = parseMetricCheckerConfig(args.contract.condition.evaluatorConfig);\n const input = getEvaluatorInputRecord(args.inputData, \"metricData\");\n const metric =\n typeof input.metric === \"string\" && input.metric.length > 0\n ? input.metric\n : config.metric;\n const observedValue =\n pickFiniteNumber(input, [\n \"observedValue\",\n \"currentValue\",\n \"metricValue\",\n \"value\",\n ]) ??\n config.observedValue ??\n config.currentValue ??\n config.metricValue ??\n null;\n if (observedValue === null) {\n return {\n result: \"inconclusive\",\n rationale: `metric_checker is awaiting data for ${metric ?? args.contract.condition.expression}.`,\n data: {\n metric,\n observedValue: null,\n operator: config.operator,\n threshold: config.threshold,\n unit: config.unit,\n },\n };\n }\n\n const comparisonSatisfied = compareMetricValue(\n config.operator,\n observedValue,\n config.threshold\n );\n const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);\n\n return {\n result,\n rationale: buildComparisonRationale({\n label: metric ?? \"metric\",\n observedValue,\n operator: config.operator,\n threshold: config.threshold,\n comparisonSatisfied,\n result,\n unit: config.unit,\n }),\n data: {\n metric,\n observedValue,\n operator: config.operator,\n threshold: config.threshold,\n unit: config.unit,\n },\n };\n}\n\nexport async function evaluateReferenceCheckCounterContract(\n args: EpistemicEvaluatorContext\n): Promise<EpistemicEvaluatorResult> {\n const config = parseReferenceCheckCounterConfig(args.contract.condition.evaluatorConfig);\n const input = getEvaluatorInputRecord(args.inputData, \"referenceCheckData\");\n const tag =\n typeof input.tag === \"string\" && input.tag.trim().length > 0\n ? input.tag.trim()\n : config.tag;\n const snapshot = await computeTaggedEvidenceCount({\n ctx: args.ctx,\n beliefNodeId: args.belief._id,\n tag,\n caseSensitive: config.caseSensitive,\n });\n const comparisonSatisfied = compareMetricValue(\n config.operator,\n snapshot.count,\n config.threshold\n );\n const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);\n\n return {\n result,\n rationale: buildComparisonRationale({\n label: `reference checks tagged \"${tag}\"`,\n observedValue: snapshot.count,\n operator: config.operator,\n threshold: config.threshold,\n comparisonSatisfied,\n result,\n }),\n data: {\n tag,\n observedValue: snapshot.count,\n referenceCheckCount: snapshot.count,\n matchedEvidenceIds: snapshot.matchedEvidenceIds,\n operator: config.operator,\n threshold: config.threshold,\n caseSensitive: config.caseSensitive ?? false,\n },\n };\n}\n\nexport async function evaluateTemporalDeadlineContract(\n args: EpistemicEvaluatorContext\n): Promise<EpistemicEvaluatorResult> {\n if (\n typeof args.contract.deadline !== \"number\" ||\n !Number.isFinite(args.contract.deadline)\n ) {\n throw new Error(\n \"temporal_deadline requires contract.deadline to be set to a finite timestamp.\"\n );\n }\n\n const config = parseTemporalDeadlineConfig(args.contract.condition.evaluatorConfig);\n const input = getEvaluatorInputRecord(args.inputData, \"temporalData\");\n const label =\n (typeof input.label === \"string\" && input.label.length > 0\n ? input.label\n : config.label) ??\n args.contract.title ??\n args.contract.condition.expression;\n const completedAt =\n pickFiniteNumber(input, [\n \"completedAt\",\n \"observedAt\",\n \"satisfiedAt\",\n \"achievedAt\",\n ]) ??\n config.completedAt ??\n config.observedAt ??\n config.satisfiedAt ??\n config.achievedAt;\n const completed =\n input.completed === true || config.completed === true || completedAt !== undefined;\n\n if (completed) {\n if (completedAt !== undefined && completedAt > args.contract.deadline) {\n return {\n result: \"expired\",\n rationale: `${label} completed at ${completedAt}, after deadline ${args.contract.deadline}.`,\n data: {\n label,\n deadline: args.contract.deadline,\n completed: true,\n completedAt,\n missedDeadline: true,\n overdueByMs: completedAt - args.contract.deadline,\n },\n };\n }\n\n const result =\n args.contract.direction === \"falsifies\" ? \"disconfirmed\" : \"confirmed\";\n return {\n result,\n rationale: `${label} completed before deadline ${args.contract.deadline}.`,\n data: {\n label,\n deadline: args.contract.deadline,\n completed: true,\n completedAt: completedAt ?? null,\n missedDeadline: false,\n },\n };\n }\n\n if (args.now > args.contract.deadline) {\n return {\n result: \"expired\",\n rationale: `${label} missed deadline ${args.contract.deadline}; temporal contract expired.`,\n data: {\n label,\n deadline: args.contract.deadline,\n completed: false,\n overdueByMs: args.now - args.contract.deadline,\n },\n };\n }\n\n return {\n result: \"inconclusive\",\n rationale: `${label} is still before deadline ${args.contract.deadline}; awaiting outcome.`,\n data: {\n label,\n deadline: args.contract.deadline,\n completed: false,\n timeRemainingMs: args.contract.deadline - args.now,\n },\n };\n}\n\nexport async function evaluateMarketIndexComparatorContract(\n args: EpistemicEvaluatorContext\n): Promise<EpistemicEvaluatorResult> {\n const config = parseMarketIndexComparatorConfig(args.contract.condition.evaluatorConfig);\n const input = getEvaluatorInputRecord(args.inputData, \"marketIndexData\");\n const subject =\n typeof input.subject === \"string\" && input.subject.length > 0\n ? input.subject\n : config.subject;\n const benchmark =\n typeof input.benchmark === \"string\" && input.benchmark.length > 0\n ? input.benchmark\n : config.benchmark;\n const subjectValue =\n pickFiniteNumber(input, [\"subjectValue\", \"primaryValue\", \"leftValue\"]) ??\n config.subjectValue ??\n config.primaryValue ??\n null;\n const benchmarkValue =\n pickFiniteNumber(input, [\"benchmarkValue\", \"comparisonValue\", \"rightValue\"]) ??\n config.benchmarkValue ??\n config.comparisonValue ??\n null;\n\n if (subjectValue === null || benchmarkValue === null) {\n return {\n result: \"inconclusive\",\n rationale: \"market_index_comparator is awaiting both subject and benchmark values.\",\n data: {\n subject,\n subjectValue,\n benchmark,\n benchmarkValue,\n operator: config.operator,\n threshold: config.threshold,\n },\n };\n }\n\n if (benchmarkValue === 0) {\n throw new Error(\n \"market_index_comparator cannot compare against a zero benchmark value.\"\n );\n }\n\n const differentialPercent =\n ((subjectValue - benchmarkValue) / Math.abs(benchmarkValue)) * 100;\n const comparisonSatisfied = compareMetricValue(\n config.operator,\n differentialPercent,\n config.threshold\n );\n const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);\n\n return {\n result,\n rationale: buildComparisonRationale({\n label: `${subject ?? \"subject\"} vs ${benchmark ?? \"benchmark\"} differential`,\n observedValue: differentialPercent,\n operator: config.operator,\n threshold: config.threshold,\n comparisonSatisfied,\n result,\n unit: \"%\",\n }),\n data: {\n subject,\n subjectValue,\n benchmark,\n benchmarkValue,\n differentialPercent,\n operator: config.operator,\n threshold: config.threshold,\n },\n };\n}\n\nexport const METRIC_COMPARATOR_EVALUATOR_NAMES = {\n evidential: \"evidential\",\n evidentialAliases: new Set([\"evidential\", \"built_in_evidential\", \"builtin_evidential\"]),\n metricChecker: \"metric_checker\",\n referenceCheckCounter: \"reference_check_counter\",\n temporalDeadline: \"temporal_deadline\",\n marketIndexComparator: \"market_index_comparator\",\n};\n"]}
@@ -0,0 +1,159 @@
1
+ import { Id, MutationCtx, QueryCtx } from './convex.js';
2
+ import { EpistemicContractEvaluationResult, EpistemicContractRecord } from '@lucern/confidence';
3
+ import 'convex/values';
4
+
5
+ /** Shared types for epistemic contract lifecycle and evaluator internals. */
6
+
7
+ type EpistemicEvaluatorResult = {
8
+ result: EpistemicContractEvaluationResult;
9
+ confidence?: number;
10
+ data?: unknown;
11
+ rationale: string;
12
+ };
13
+ type EpistemicEvaluatorContext = {
14
+ belief: BeliefNodeDoc;
15
+ contract: ContractDoc;
16
+ ctx: MutationCtx;
17
+ now: number;
18
+ resultData?: unknown;
19
+ trigger: string;
20
+ inputData?: unknown;
21
+ };
22
+ type EpistemicEvaluator = {
23
+ name: string;
24
+ evaluate(args: EpistemicEvaluatorContext): Promise<EpistemicEvaluatorResult> | EpistemicEvaluatorResult;
25
+ };
26
+ type BeliefNodeDoc = {
27
+ _id: Id<"epistemicNodes">;
28
+ nodeType: "belief";
29
+ canonicalText: string;
30
+ projectId?: string;
31
+ topicId?: Id<"topics"> | string;
32
+ confidence?: number;
33
+ status?: string;
34
+ [key: string]: unknown;
35
+ };
36
+ type ContractDoc = EpistemicContractRecord<Id<"epistemicNodes">, Id<"topics"> | string | undefined> & {
37
+ _id: string;
38
+ _creationTime: number;
39
+ };
40
+ type ContractEvaluationDoc = {
41
+ contractId: string;
42
+ beliefNodeId: Id<"epistemicNodes">;
43
+ result: EpistemicContractEvaluationResult;
44
+ evaluatedAt: number;
45
+ evaluator: string;
46
+ trigger: string;
47
+ resultData?: unknown;
48
+ modulationApplied: boolean;
49
+ confidenceDelta?: number;
50
+ confidenceBefore?: number;
51
+ confidenceAfter?: number;
52
+ beliefConfidenceId?: Id<"beliefConfidence">;
53
+ modulationRationale?: string;
54
+ topicId?: Id<"topics"> | string;
55
+ _id: string;
56
+ _creationTime: number;
57
+ };
58
+ type EvidenceEdgeDoc = {
59
+ fromNodeId: Id<"epistemicNodes">;
60
+ weight?: number;
61
+ updatedAt?: number;
62
+ createdAt?: number;
63
+ _creationTime?: number;
64
+ };
65
+ type EvidenceNodeDoc = {
66
+ _id: Id<"epistemicNodes">;
67
+ nodeType: string;
68
+ status?: string;
69
+ metadata?: unknown;
70
+ };
71
+ type ContradictionStatusCounts = {
72
+ activeCount: number;
73
+ resolvedCount: number;
74
+ };
75
+ type EvidenceFreshness = {
76
+ newestAgeMs: number | null;
77
+ oldestAgeMs: number | null;
78
+ newestEdgeAt: number | null;
79
+ oldestEdgeAt: number | null;
80
+ edgeCount: number;
81
+ };
82
+ type EvidentialMetric = "evidence_count" | "contradiction_status" | "edge_freshness" | "dependent_count";
83
+ type EvidentialAction = "modulate_confidence" | "flag_review" | "archive";
84
+ type EvidentialEvaluatorConfig = {
85
+ metric: EvidentialMetric;
86
+ operator: "gte" | "lte" | "eq" | "gt" | "lt";
87
+ threshold: number;
88
+ action?: EvidentialAction;
89
+ actionParams?: {
90
+ targetConfidence?: number;
91
+ rationale?: string;
92
+ };
93
+ };
94
+ type EvidentialMetricSnapshot = {
95
+ metric: EvidentialMetric;
96
+ value: number | null;
97
+ data: Record<string, unknown>;
98
+ };
99
+ type MetricCheckerEvaluatorConfig = {
100
+ metric?: string;
101
+ operator: "gte" | "lte" | "eq" | "gt" | "lt";
102
+ threshold: number;
103
+ observedValue?: number;
104
+ currentValue?: number;
105
+ metricValue?: number;
106
+ unit?: string;
107
+ };
108
+ type ReferenceCheckCounterConfig = {
109
+ tag: string;
110
+ operator: "gte" | "lte" | "eq" | "gt" | "lt";
111
+ threshold: number;
112
+ caseSensitive?: boolean;
113
+ };
114
+ type TemporalDeadlineEvaluatorConfig = {
115
+ label?: string;
116
+ completed?: boolean;
117
+ completedAt?: number;
118
+ observedAt?: number;
119
+ satisfiedAt?: number;
120
+ achievedAt?: number;
121
+ };
122
+ type MarketIndexComparatorConfig = {
123
+ subject?: string;
124
+ subjectValue?: number;
125
+ primaryValue?: number;
126
+ benchmark?: string;
127
+ benchmarkValue?: number;
128
+ comparisonValue?: number;
129
+ operator: "gte" | "lte" | "eq" | "gt" | "lt";
130
+ threshold: number;
131
+ };
132
+ type ContractEvaluationExecution = {
133
+ evaluationId: string;
134
+ result: EpistemicContractEvaluationResult;
135
+ status: ContractDoc["status"];
136
+ confidenceBefore: number;
137
+ confidenceAfter: number;
138
+ rationale: string;
139
+ data?: unknown;
140
+ currentConfidence: number;
141
+ };
142
+ type TriggerBatchResult = {
143
+ totalContracts: number;
144
+ processedCount: number;
145
+ overflowCount: number;
146
+ scheduledOverflow: boolean;
147
+ batchSize: number;
148
+ executionTimeMs: number;
149
+ trigger: string;
150
+ results: Array<{
151
+ contractId: string;
152
+ result: EpistemicContractEvaluationResult;
153
+ status: ContractDoc["status"];
154
+ confidenceAfter: number;
155
+ }>;
156
+ };
157
+ type ContractReadCtx = MutationCtx | QueryCtx;
158
+
159
+ export type { BeliefNodeDoc, ContractDoc, ContractEvaluationDoc, ContractEvaluationExecution, ContractReadCtx, ContradictionStatusCounts, EpistemicEvaluator, EpistemicEvaluatorContext, EpistemicEvaluatorResult, EvidenceEdgeDoc, EvidenceFreshness, EvidenceNodeDoc, EvidentialAction, EvidentialEvaluatorConfig, EvidentialMetric, EvidentialMetricSnapshot, MarketIndexComparatorConfig, MetricCheckerEvaluatorConfig, ReferenceCheckCounterConfig, TemporalDeadlineEvaluatorConfig, TriggerBatchResult };