@lucern/confidence 0.1.0-alpha.2

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 (65) hide show
  1. package/README.md +34 -0
  2. package/dist/index.d.ts +17 -0
  3. package/dist/index.js +1833 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/v1/index.d.ts +17 -0
  6. package/dist/v1/index.js +1833 -0
  7. package/dist/v1/index.js.map +1 -0
  8. package/dist/v1/interfaces.d.ts +28 -0
  9. package/dist/v1/interfaces.js +3 -0
  10. package/dist/v1/interfaces.js.map +1 -0
  11. package/dist/v1/operations/approximation.d.ts +8 -0
  12. package/dist/v1/operations/approximation.js +219 -0
  13. package/dist/v1/operations/approximation.js.map +1 -0
  14. package/dist/v1/operations/bridge/index.d.ts +12 -0
  15. package/dist/v1/operations/bridge/index.js +89 -0
  16. package/dist/v1/operations/bridge/index.js.map +1 -0
  17. package/dist/v1/operations/canonical.d.ts +7 -0
  18. package/dist/v1/operations/canonical.js +199 -0
  19. package/dist/v1/operations/canonical.js.map +1 -0
  20. package/dist/v1/operations/contracts/epistemicContract.d.ts +51 -0
  21. package/dist/v1/operations/contracts/epistemicContract.js +320 -0
  22. package/dist/v1/operations/contracts/epistemicContract.js.map +1 -0
  23. package/dist/v1/operations/contradiction/detectTupleContradiction.d.ts +13 -0
  24. package/dist/v1/operations/contradiction/detectTupleContradiction.js +40 -0
  25. package/dist/v1/operations/contradiction/detectTupleContradiction.js.map +1 -0
  26. package/dist/v1/operations/contradiction/index.d.ts +2 -0
  27. package/dist/v1/operations/contradiction/index.js +40 -0
  28. package/dist/v1/operations/contradiction/index.js.map +1 -0
  29. package/dist/v1/operations/dynamics/cascade.d.ts +6 -0
  30. package/dist/v1/operations/dynamics/cascade.js +56 -0
  31. package/dist/v1/operations/dynamics/cascade.js.map +1 -0
  32. package/dist/v1/operations/dynamics/decay.d.ts +25 -0
  33. package/dist/v1/operations/dynamics/decay.js +271 -0
  34. package/dist/v1/operations/dynamics/decay.js.map +1 -0
  35. package/dist/v1/operations/dynamics/defeat.d.ts +6 -0
  36. package/dist/v1/operations/dynamics/defeat.js +134 -0
  37. package/dist/v1/operations/dynamics/defeat.js.map +1 -0
  38. package/dist/v1/operations/dynamics/propagation.d.ts +58 -0
  39. package/dist/v1/operations/dynamics/propagation.js +399 -0
  40. package/dist/v1/operations/dynamics/propagation.js.map +1 -0
  41. package/dist/v1/operations/dynamics/revision.d.ts +24 -0
  42. package/dist/v1/operations/dynamics/revision.js +111 -0
  43. package/dist/v1/operations/dynamics/revision.js.map +1 -0
  44. package/dist/v1/operations/index.d.ts +2 -0
  45. package/dist/v1/operations/index.js +66 -0
  46. package/dist/v1/operations/index.js.map +1 -0
  47. package/dist/v1/operations/lucern.d.ts +14 -0
  48. package/dist/v1/operations/lucern.js +1280 -0
  49. package/dist/v1/operations/lucern.js.map +1 -0
  50. package/dist/v1/operations/operatorTaxonomy.d.ts +366 -0
  51. package/dist/v1/operations/operatorTaxonomy.js +508 -0
  52. package/dist/v1/operations/operatorTaxonomy.js.map +1 -0
  53. package/dist/v1/operations/scoring.d.ts +28 -0
  54. package/dist/v1/operations/scoring.js +107 -0
  55. package/dist/v1/operations/scoring.js.map +1 -0
  56. package/dist/v1/operations/subjectiveLogic/index.d.ts +26 -0
  57. package/dist/v1/operations/subjectiveLogic/index.js +285 -0
  58. package/dist/v1/operations/subjectiveLogic/index.js.map +1 -0
  59. package/dist/v1/operations/temporalDecay.d.ts +24 -0
  60. package/dist/v1/operations/temporalDecay.js +66 -0
  61. package/dist/v1/operations/temporalDecay.js.map +1 -0
  62. package/dist/v1/types.d.ts +208 -0
  63. package/dist/v1/types.js +3 -0
  64. package/dist/v1/types.js.map +1 -0
  65. package/package.json +46 -0
package/dist/index.js ADDED
@@ -0,0 +1,1833 @@
1
+ // src/v1/operations/subjectiveLogic/index.ts
2
+ function opinion(belief, disbelief, uncertainty, baseRate = 0.5) {
3
+ const b = Math.max(0, Math.min(1, belief));
4
+ const d = Math.max(0, Math.min(1, disbelief));
5
+ const u = Math.max(0, Math.min(1, uncertainty));
6
+ const a = Math.max(0, Math.min(1, baseRate));
7
+ const sum = b + d + u;
8
+ if (sum === 0) {
9
+ return { b: 0, d: 0, u: 1, a };
10
+ }
11
+ return {
12
+ b: b / sum,
13
+ d: d / sum,
14
+ u: u / sum,
15
+ a
16
+ };
17
+ }
18
+ function vacuous(baseRate = 0.5) {
19
+ return { b: 0, d: 0, u: 1, a: baseRate };
20
+ }
21
+ function dogmatic(probability, baseRate = 0.5) {
22
+ const p = Math.max(0, Math.min(1, probability));
23
+ return { b: p, d: 1 - p, u: 0, a: baseRate };
24
+ }
25
+ function project(o) {
26
+ return o.b + o.a * o.u;
27
+ }
28
+ function confidenceLevel(o) {
29
+ const projected = project(o);
30
+ if (o.u > 0.5) {
31
+ return "low";
32
+ }
33
+ if (projected >= 0.8 && o.u < 0.2) {
34
+ return "high";
35
+ }
36
+ if (projected >= 0.6) {
37
+ return "medium";
38
+ }
39
+ return "low";
40
+ }
41
+ function cumulativeFusion(left, right) {
42
+ if (left.u === 0 && right.u === 0) {
43
+ return opinion(
44
+ (left.b + right.b) / 2,
45
+ (left.d + right.d) / 2,
46
+ 0,
47
+ (left.a + right.a) / 2
48
+ );
49
+ }
50
+ const k = left.u + right.u - left.u * right.u;
51
+ if (k === 0) {
52
+ return vacuous((left.a + right.a) / 2);
53
+ }
54
+ return opinion(
55
+ (left.b * right.u + right.b * left.u) / k,
56
+ (left.d * right.u + right.d * left.u) / k,
57
+ left.u * right.u / k,
58
+ (left.a + right.a) / 2
59
+ );
60
+ }
61
+ function averagingFusion(left, right) {
62
+ if (left.u === 0 && right.u === 0) {
63
+ return opinion(
64
+ (left.b + right.b) / 2,
65
+ (left.d + right.d) / 2,
66
+ 0,
67
+ (left.a + right.a) / 2
68
+ );
69
+ }
70
+ const k = left.u + right.u;
71
+ if (k === 0) {
72
+ return vacuous((left.a + right.a) / 2);
73
+ }
74
+ return opinion(
75
+ (left.b * right.u + right.b * left.u) / k,
76
+ (left.d * right.u + right.d * left.u) / k,
77
+ 2 * left.u * right.u / k,
78
+ (left.a + right.a) / 2
79
+ );
80
+ }
81
+ function trustDiscount(sourceOpinion, trust) {
82
+ const weight = Math.max(0, Math.min(1, Math.abs(trust)));
83
+ return opinion(
84
+ weight * sourceOpinion.b,
85
+ weight * sourceOpinion.d,
86
+ 1 - weight * (sourceOpinion.b + sourceOpinion.d),
87
+ sourceOpinion.a
88
+ );
89
+ }
90
+ var EPSILON = 1e-9;
91
+ function childBaseRateFallback(ifTrue, ifFalse, fallbackBaseRate) {
92
+ if (fallbackBaseRate !== void 0) {
93
+ return Math.max(0, Math.min(1, fallbackBaseRate));
94
+ }
95
+ if (Math.abs(ifTrue.a - ifFalse.a) <= EPSILON) {
96
+ return ifTrue.a;
97
+ }
98
+ return (ifTrue.a + ifFalse.a) / 2;
99
+ }
100
+ function computeConditionalDeductionBaseRate(opinionA, ifTrue, ifFalse, fallbackBaseRate) {
101
+ const denominator = 1 - opinionA.a * ifTrue.u - (1 - opinionA.a) * ifFalse.u;
102
+ if (ifTrue.u + ifFalse.u < 2 - EPSILON && Math.abs(denominator) > EPSILON) {
103
+ const baseRate = (opinionA.a * ifTrue.b + (1 - opinionA.a) * ifFalse.b) / denominator;
104
+ if (baseRate >= -EPSILON && baseRate <= 1 + EPSILON) {
105
+ return Math.max(0, Math.min(1, baseRate));
106
+ }
107
+ }
108
+ return fallbackBaseRate;
109
+ }
110
+ function safeCorrectionTerm(numerator, denominator) {
111
+ if (Math.abs(denominator) <= EPSILON) {
112
+ return void 0;
113
+ }
114
+ const value = numerator / denominator;
115
+ if (!Number.isFinite(value)) {
116
+ return void 0;
117
+ }
118
+ return Math.max(0, value);
119
+ }
120
+ function conditionalDeduction(opinionA, ifTrue, ifFalse, fallbackBaseRate) {
121
+ const fallbackChildBaseRate = childBaseRateFallback(
122
+ ifTrue,
123
+ ifFalse,
124
+ fallbackBaseRate
125
+ );
126
+ const childBaseRate = computeConditionalDeductionBaseRate(
127
+ opinionA,
128
+ ifTrue,
129
+ ifFalse,
130
+ fallbackChildBaseRate
131
+ );
132
+ const projectedAntecedent = project(opinionA);
133
+ const projectedAntecedentComplement = 1 - projectedAntecedent;
134
+ const intermediateBelief = opinionA.b * ifTrue.b + opinionA.d * ifFalse.b + opinionA.u * (ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a));
135
+ const intermediateDisbelief = opinionA.b * ifTrue.d + opinionA.d * ifFalse.d + opinionA.u * (ifTrue.d * opinionA.a + ifFalse.d * (1 - opinionA.a));
136
+ const intermediateUncertainty = opinionA.b * ifTrue.u + opinionA.d * ifFalse.u + opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));
137
+ const projectedVacuousDeduction = ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a) + childBaseRate * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));
138
+ const projectedConditionalA = ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);
139
+ let correction = 0;
140
+ if (ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d || ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d) {
141
+ correction = 0;
142
+ } else if (ifTrue.b > ifFalse.b && ifTrue.d <= ifFalse.d) {
143
+ const beliefGap = ifTrue.b - ifFalse.b;
144
+ const disbeliefGap = ifFalse.d - ifTrue.d;
145
+ if (projectedVacuousDeduction <= projectedConditionalA && projectedAntecedent <= opinionA.a) {
146
+ correction = safeCorrectionTerm(
147
+ opinionA.a * opinionA.u * (intermediateBelief - ifTrue.b),
148
+ projectedAntecedent * childBaseRate
149
+ ) ?? 0;
150
+ } else if (projectedVacuousDeduction <= projectedConditionalA && projectedAntecedent > opinionA.a) {
151
+ correction = safeCorrectionTerm(
152
+ opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,
153
+ projectedAntecedentComplement * childBaseRate * disbeliefGap
154
+ ) ?? 0;
155
+ } else if (projectedVacuousDeduction > projectedConditionalA && projectedAntecedent <= opinionA.a) {
156
+ correction = safeCorrectionTerm(
157
+ (1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b) * disbeliefGap,
158
+ projectedAntecedent * (1 - childBaseRate) * beliefGap
159
+ ) ?? 0;
160
+ } else {
161
+ correction = safeCorrectionTerm(
162
+ (1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d),
163
+ projectedAntecedentComplement * (1 - childBaseRate)
164
+ ) ?? 0;
165
+ }
166
+ } else {
167
+ const beliefGap = ifFalse.b - ifTrue.b;
168
+ const disbeliefGap = ifTrue.d - ifFalse.d;
169
+ if (projectedVacuousDeduction <= projectedConditionalA && projectedAntecedent <= opinionA.a) {
170
+ correction = safeCorrectionTerm(
171
+ (1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,
172
+ projectedAntecedent * childBaseRate * disbeliefGap
173
+ ) ?? 0;
174
+ } else if (projectedVacuousDeduction <= projectedConditionalA && projectedAntecedent > opinionA.a) {
175
+ correction = safeCorrectionTerm(
176
+ (1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b),
177
+ projectedAntecedentComplement * childBaseRate
178
+ ) ?? 0;
179
+ } else if (projectedVacuousDeduction > projectedConditionalA && projectedAntecedent <= opinionA.a) {
180
+ correction = safeCorrectionTerm(
181
+ opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d),
182
+ projectedAntecedent * (1 - childBaseRate)
183
+ ) ?? 0;
184
+ } else {
185
+ correction = safeCorrectionTerm(
186
+ opinionA.a * opinionA.u * (intermediateBelief - ifTrue.b) * disbeliefGap,
187
+ projectedAntecedentComplement * (1 - childBaseRate) * beliefGap
188
+ ) ?? 0;
189
+ }
190
+ }
191
+ return opinion(
192
+ intermediateBelief - childBaseRate * correction,
193
+ intermediateDisbelief - (1 - childBaseRate) * correction,
194
+ intermediateUncertainty + correction,
195
+ childBaseRate
196
+ );
197
+ }
198
+ function conditionalAbduction(opinionY, ifTrue, ifFalse, baseRateX) {
199
+ const priorX = Math.max(0, Math.min(1, baseRateX));
200
+ const probabilityY = project(opinionY);
201
+ const probabilityGivenTrue = project(ifTrue);
202
+ const probabilityGivenFalse = project(ifFalse);
203
+ const posteriorIfYDenominator = probabilityGivenTrue * priorX + probabilityGivenFalse * (1 - priorX);
204
+ const posteriorIfY = posteriorIfYDenominator === 0 ? priorX : probabilityGivenTrue * priorX / posteriorIfYDenominator;
205
+ const posteriorIfNotYDenominator = (1 - probabilityGivenTrue) * priorX + (1 - probabilityGivenFalse) * (1 - priorX);
206
+ const posteriorIfNotY = posteriorIfNotYDenominator === 0 ? priorX : (1 - probabilityGivenTrue) * priorX / posteriorIfNotYDenominator;
207
+ const projectedX = probabilityY * posteriorIfY + (1 - probabilityY) * posteriorIfNotY;
208
+ const uncertainty = Math.max(
209
+ opinionY.u * 0.5,
210
+ probabilityY * ifTrue.u + (1 - probabilityY) * ifFalse.u
211
+ );
212
+ return opinion(
213
+ projectedX * (1 - uncertainty),
214
+ (1 - projectedX) * (1 - uncertainty),
215
+ uncertainty,
216
+ priorX
217
+ );
218
+ }
219
+ function negate(o) {
220
+ return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };
221
+ }
222
+ function constraintFusion(left, right, mode = "pressure") {
223
+ if (mode === "redistribute") {
224
+ const leftProjected = project(left);
225
+ const rightProjected = project(right);
226
+ const total = leftProjected + rightProjected;
227
+ if (total <= 1) {
228
+ return { o1: left, o2: right };
229
+ }
230
+ const scale = 1 / total;
231
+ return {
232
+ o1: opinion(
233
+ left.b * scale,
234
+ left.d + left.b * (1 - scale),
235
+ left.u,
236
+ left.a
237
+ ),
238
+ o2: opinion(
239
+ right.b * scale,
240
+ right.d + right.b * (1 - scale),
241
+ right.u,
242
+ right.a
243
+ )
244
+ };
245
+ }
246
+ const pressureLeft = right.b * 0.5;
247
+ const pressureRight = left.b * 0.5;
248
+ return {
249
+ o1: opinion(
250
+ left.b - pressureLeft * 0.3,
251
+ left.d + pressureLeft * 0.3,
252
+ left.u,
253
+ left.a
254
+ ),
255
+ o2: opinion(
256
+ right.b - pressureRight * 0.3,
257
+ right.d + pressureRight * 0.3,
258
+ right.u,
259
+ right.a
260
+ )
261
+ };
262
+ }
263
+ function evidenceBalance(o) {
264
+ const total = o.b + o.d;
265
+ if (total === 0) {
266
+ return 0;
267
+ }
268
+ return (o.b - o.d) / total;
269
+ }
270
+ function areTensioned(left, right) {
271
+ return project(left) > 0.5 && project(right) > 0.5 && (left.d > 0.2 || right.d > 0.2);
272
+ }
273
+ function informationGain(o) {
274
+ if (o.u === 0) {
275
+ return 0;
276
+ }
277
+ if (o.u === 1) {
278
+ return 1;
279
+ }
280
+ return o.u * (1 - Math.abs(o.b - o.d));
281
+ }
282
+
283
+ // src/v1/operations/temporalDecay.ts
284
+ var DEFAULT_TEMPORAL_DECAY_HALF_LIFE_MS = 90 * 24 * 60 * 60 * 1e3;
285
+ function toEpochMs(value) {
286
+ if (typeof value === "number" && Number.isFinite(value)) {
287
+ return value;
288
+ }
289
+ if (value instanceof Date) {
290
+ const epochMs = value.getTime();
291
+ return Number.isFinite(epochMs) ? epochMs : void 0;
292
+ }
293
+ return void 0;
294
+ }
295
+ function normalizeHalfLifeMs(halfLifeMs) {
296
+ if (halfLifeMs === void 0 || !Number.isFinite(halfLifeMs)) {
297
+ return 0;
298
+ }
299
+ return Math.max(0, halfLifeMs);
300
+ }
301
+ function temporalDecay(sourceOpinion, now, decayParams) {
302
+ const halfLifeMs = normalizeHalfLifeMs(decayParams.halfLifeMs);
303
+ if (halfLifeMs === 0) {
304
+ return { ...sourceOpinion };
305
+ }
306
+ const nowMs = toEpochMs(now);
307
+ const referenceTimeMs = toEpochMs(decayParams.referenceTime);
308
+ if (nowMs === void 0 || referenceTimeMs === void 0) {
309
+ return { ...sourceOpinion };
310
+ }
311
+ const ageMs = Math.max(0, nowMs - referenceTimeMs);
312
+ if (ageMs === 0) {
313
+ return { ...sourceOpinion };
314
+ }
315
+ const retainedEvidenceWeight = Math.pow(0.5, ageMs / halfLifeMs);
316
+ return trustDiscount(sourceOpinion, retainedEvidenceWeight);
317
+ }
318
+
319
+ // src/v1/operations/bridge/index.ts
320
+ var DEFAULT_NON_INFORMATIVE_WEIGHT = 2;
321
+ function clamp01(value) {
322
+ return Math.max(0, Math.min(1, value));
323
+ }
324
+ function clampNonNegative(value) {
325
+ return Number.isFinite(value) ? Math.max(0, value) : 0;
326
+ }
327
+ function normalizeNonInformativeWeight(weight) {
328
+ if (weight === void 0) {
329
+ return DEFAULT_NON_INFORMATIVE_WEIGHT;
330
+ }
331
+ return Number.isFinite(weight) ? Math.max(0, weight) : DEFAULT_NON_INFORMATIVE_WEIGHT;
332
+ }
333
+ function normalizeBaseRateVector(baseRate, size) {
334
+ if (size === 0) {
335
+ return [];
336
+ }
337
+ const fallback = Array.from({ length: size }, () => 1 / size);
338
+ if (!baseRate) {
339
+ return fallback;
340
+ }
341
+ if (baseRate.length !== size) {
342
+ throw new Error(
343
+ `Base-rate vector length ${baseRate.length} must match evidence vector length ${size}.`
344
+ );
345
+ }
346
+ const normalized = baseRate.map((value) => clampNonNegative(value));
347
+ const total = normalized.reduce((sum, value) => sum + value, 0);
348
+ if (total === 0) {
349
+ return fallback;
350
+ }
351
+ return normalized.map((value) => value / total);
352
+ }
353
+ function opinionFromDirichlet(alpha, nonInformativeWeight = DEFAULT_NON_INFORMATIVE_WEIGHT, baseRate) {
354
+ const evidence = alpha.map((value) => clampNonNegative(value));
355
+ const safeWeight = normalizeNonInformativeWeight(nonInformativeWeight);
356
+ const normalizedBaseRate = normalizeBaseRateVector(baseRate, evidence.length);
357
+ const totalEvidence = evidence.reduce((sum, value) => sum + value, 0);
358
+ const denominator = totalEvidence + safeWeight;
359
+ if (denominator === 0) {
360
+ return {
361
+ b: evidence.map(() => 0),
362
+ u: 1,
363
+ a: normalizedBaseRate
364
+ };
365
+ }
366
+ return {
367
+ b: evidence.map((value) => value / denominator),
368
+ u: safeWeight / denominator,
369
+ a: normalizedBaseRate
370
+ };
371
+ }
372
+ function projectDirichletOpinion(opinion2) {
373
+ return opinion2.b.map(
374
+ (belief, index) => belief + (opinion2.a[index] ?? 0) * opinion2.u
375
+ );
376
+ }
377
+ function opinionFromBeta(alpha, beta, nonInformativeWeight = DEFAULT_NON_INFORMATIVE_WEIGHT, baseRate = 0.5) {
378
+ const dirichlet = opinionFromDirichlet(
379
+ [alpha, beta],
380
+ nonInformativeWeight,
381
+ [clamp01(baseRate), 1 - clamp01(baseRate)]
382
+ );
383
+ return {
384
+ b: dirichlet.b[0] ?? 0,
385
+ d: dirichlet.b[1] ?? 0,
386
+ u: dirichlet.u,
387
+ a: dirichlet.a[0] ?? clamp01(baseRate)
388
+ };
389
+ }
390
+ function betaFromOpinion(opinion2, nonInformativeWeight = DEFAULT_NON_INFORMATIVE_WEIGHT) {
391
+ if (opinion2.u === 0) {
392
+ return {
393
+ alpha: Number.POSITIVE_INFINITY,
394
+ beta: Number.POSITIVE_INFINITY
395
+ };
396
+ }
397
+ const safeWeight = normalizeNonInformativeWeight(nonInformativeWeight);
398
+ const scale = safeWeight / opinion2.u;
399
+ return {
400
+ alpha: opinion2.b * scale,
401
+ beta: opinion2.d * scale
402
+ };
403
+ }
404
+
405
+ // src/v1/operations/scoring.ts
406
+ function finiteNumber(value) {
407
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
408
+ }
409
+ function clamp012(value) {
410
+ return Math.max(0, Math.min(1, value));
411
+ }
412
+ function confidenceFromOpinion(opinion2) {
413
+ return clamp012(opinion2.b + opinion2.a * opinion2.u);
414
+ }
415
+ function confidenceFromSL(belief, _disbelief, uncertainty, baseRate = 0.5) {
416
+ return confidenceFromOpinion({
417
+ b: belief,
418
+ u: uncertainty,
419
+ a: baseRate
420
+ });
421
+ }
422
+ function toStoredOpinionFields(opinion2) {
423
+ return {
424
+ belief: opinion2.b,
425
+ disbelief: opinion2.d,
426
+ uncertainty: opinion2.u,
427
+ baseRate: opinion2.a
428
+ };
429
+ }
430
+ function readOpinionFromRecord(source, fallback = {}) {
431
+ const record = source && typeof source === "object" ? source : {};
432
+ return {
433
+ b: finiteNumber(record.b) ?? finiteNumber(record.belief) ?? finiteNumber(record.slBelief) ?? finiteNumber(record.opinion_b) ?? fallback.b ?? 0,
434
+ d: finiteNumber(record.d) ?? finiteNumber(record.disbelief) ?? finiteNumber(record.slDisbelief) ?? finiteNumber(record.opinion_d) ?? fallback.d ?? 0,
435
+ u: finiteNumber(record.u) ?? finiteNumber(record.uncertainty) ?? finiteNumber(record.slUncertainty) ?? finiteNumber(record.opinion_u) ?? fallback.u ?? 1,
436
+ a: finiteNumber(record.a) ?? finiteNumber(record.baseRate) ?? finiteNumber(record.slBaseRate) ?? finiteNumber(record.opinion_a) ?? fallback.a ?? 0.5
437
+ };
438
+ }
439
+ function opinionFromScalar(value, mode, options) {
440
+ const clampedValue = clamp012(value);
441
+ const baseRate = clamp012(options?.baseRate ?? 0.5);
442
+ switch (mode) {
443
+ case "base_rate":
444
+ return {
445
+ b: 0,
446
+ d: 0,
447
+ u: 1,
448
+ a: clampedValue
449
+ };
450
+ case "dogmatic":
451
+ return {
452
+ b: clampedValue,
453
+ d: 1 - clampedValue,
454
+ u: 0,
455
+ a: baseRate
456
+ };
457
+ case "projected_with_u": {
458
+ const uncertainty = options?.uncertainty;
459
+ if (uncertainty === void 0) {
460
+ throw new Error(
461
+ 'opinionFromScalar(value, "projected_with_u") requires options.uncertainty.'
462
+ );
463
+ }
464
+ const clampedUncertainty = clamp012(uncertainty);
465
+ const evidenceWeight = 1 - clampedUncertainty;
466
+ return {
467
+ b: clampedValue * evidenceWeight,
468
+ d: (1 - clampedValue) * evidenceWeight,
469
+ u: clampedUncertainty,
470
+ a: baseRate
471
+ };
472
+ }
473
+ }
474
+ throw new Error(`Unsupported opinionFromScalar mode: ${mode}`);
475
+ }
476
+ function toDogmaticOpinion(confidence, baseRate = 0.5) {
477
+ return opinionFromScalar(confidence, "dogmatic", { baseRate });
478
+ }
479
+ function opinionFromBaseRate(probability) {
480
+ return vacuous(clamp012(probability));
481
+ }
482
+ function opinionFromDogmatic(probability, baseRate = 0.5) {
483
+ return dogmatic(clamp012(probability), clamp012(baseRate));
484
+ }
485
+ function opinionFromProjected(probability, uncertainty, baseRate = 0.5) {
486
+ const p = clamp012(probability);
487
+ const u = clamp012(uncertainty);
488
+ const remainingMass = 1 - u;
489
+ return {
490
+ b: p * remainingMass,
491
+ d: (1 - p) * remainingMass,
492
+ u,
493
+ a: clamp012(baseRate)
494
+ };
495
+ }
496
+ function hasProjectedOpinionChanged(current, next, tolerance = 0.01) {
497
+ return Math.abs(confidenceFromOpinion(next) - confidenceFromOpinion(current)) >= tolerance;
498
+ }
499
+
500
+ // src/v1/operations/contradiction/detectTupleContradiction.ts
501
+ var DEFAULT_TUPLE_CONTRADICTION_BELIEF_THRESHOLD = 0.7;
502
+ var DEFAULT_TUPLE_CONTRADICTION_DISBELIEF_THRESHOLD = 0.7;
503
+ function normalizeTupleContradictionPolicy(policy = {}) {
504
+ return {
505
+ beliefThreshold: clamp012(
506
+ policy.beliefThreshold ?? DEFAULT_TUPLE_CONTRADICTION_BELIEF_THRESHOLD
507
+ ),
508
+ disbeliefThreshold: clamp012(
509
+ policy.disbeliefThreshold ?? DEFAULT_TUPLE_CONTRADICTION_DISBELIEF_THRESHOLD
510
+ )
511
+ };
512
+ }
513
+ function detectTupleContradiction(opinion2, tauB = DEFAULT_TUPLE_CONTRADICTION_BELIEF_THRESHOLD, tauD = DEFAULT_TUPLE_CONTRADICTION_DISBELIEF_THRESHOLD) {
514
+ return opinion2.b > tauB && opinion2.d > tauD;
515
+ }
516
+ function evaluateTupleContradictionTransition(args) {
517
+ const policy = normalizeTupleContradictionPolicy(args.policy);
518
+ const tupleContradicted = detectTupleContradiction(
519
+ args.opinion,
520
+ policy.beliefThreshold,
521
+ policy.disbeliefThreshold
522
+ );
523
+ const previousTupleContradicted = Boolean(args.previousTupleContradicted);
524
+ return {
525
+ tupleContradicted,
526
+ crossedIntoTupleContradiction: !previousTupleContradicted && tupleContradicted,
527
+ crossedOutOfTupleContradiction: previousTupleContradicted && !tupleContradicted,
528
+ policy
529
+ };
530
+ }
531
+
532
+ // src/v1/operations/dynamics/cascade.ts
533
+ function dampedDependencyOpinion(dependencyOpinion, beliefOpinion, mode = "continuous", threshold = 0.3) {
534
+ const dependencyProjection = project(dependencyOpinion);
535
+ if (mode === "threshold") {
536
+ if (dependencyProjection < threshold) {
537
+ return opinion(
538
+ 0,
539
+ beliefOpinion.d + beliefOpinion.b * 0.5,
540
+ 0.5,
541
+ beliefOpinion.a
542
+ );
543
+ }
544
+ return beliefOpinion;
545
+ }
546
+ const dampingFactor = Math.pow(dependencyProjection, 0.5);
547
+ return opinion(
548
+ beliefOpinion.b * dampingFactor,
549
+ beliefOpinion.d + beliefOpinion.b * (1 - dampingFactor) * 0.3,
550
+ beliefOpinion.u + beliefOpinion.b * (1 - dampingFactor) * 0.7,
551
+ beliefOpinion.a
552
+ );
553
+ }
554
+ function dampedDependencyCascade(dependencyOpinion, beliefOpinion, mode = "continuous") {
555
+ return {
556
+ opinion: dampedDependencyOpinion(dependencyOpinion, beliefOpinion, mode),
557
+ operator: "dependency_cascade",
558
+ rationale: `Damped dependency cascade (${mode}): prerequisite at ${project(
559
+ dependencyOpinion
560
+ ).toFixed(2)}`
561
+ };
562
+ }
563
+
564
+ // src/v1/operations/dynamics/defeat.ts
565
+ function applyNegativeSupport(source, target, weight, metadata = {}) {
566
+ if (metadata.constraint === "xor") {
567
+ const result = constraintFusion(
568
+ source,
569
+ target,
570
+ metadata.normalization ?? "pressure"
571
+ );
572
+ return {
573
+ opinion: result.o2,
574
+ operator: "constraint_fusion",
575
+ rationale: `XOR constraint: source belief at ${project(source).toFixed(
576
+ 2
577
+ )} pressures target`
578
+ };
579
+ }
580
+ const discounted = trustDiscount(negate(source), Math.abs(weight));
581
+ return {
582
+ opinion: cumulativeFusion(target, discounted),
583
+ operator: "cumulative_fusion",
584
+ rationale: `Contradicting evidence (weight=${weight.toFixed(
585
+ 2
586
+ )}) from source at ${project(source).toFixed(2)}`
587
+ };
588
+ }
589
+ function applyNegativeEvidence(source, target, weight) {
590
+ const discounted = trustDiscount(negate(source), Math.abs(weight));
591
+ return {
592
+ opinion: cumulativeFusion(target, discounted),
593
+ operator: "cumulative_fusion",
594
+ rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`
595
+ };
596
+ }
597
+
598
+ // src/v1/operations/dynamics/propagation.ts
599
+ var EDGE_PROPAGATION_RULES = {
600
+ supports: {
601
+ direction: "outgoing",
602
+ handler: (source, target, weight, metadata) => {
603
+ if (weight < 0) {
604
+ return applyNegativeSupport(source, target, weight, metadata);
605
+ }
606
+ const discounted = trustDiscount(source, weight);
607
+ return {
608
+ opinion: cumulativeFusion(target, discounted),
609
+ operator: "cumulative_fusion",
610
+ rationale: `Supporting evidence (weight=${weight.toFixed(
611
+ 2
612
+ )}) from source at ${project(source).toFixed(2)}`
613
+ };
614
+ }
615
+ },
616
+ informs: {
617
+ direction: "outgoing",
618
+ handler: (source, target, weight) => {
619
+ if (weight < 0) {
620
+ return applyNegativeEvidence(source, target, weight);
621
+ }
622
+ const discounted = trustDiscount(source, Math.abs(weight));
623
+ return {
624
+ opinion: cumulativeFusion(target, discounted),
625
+ operator: "cumulative_fusion",
626
+ rationale: `Supporting evidence (weight=${weight.toFixed(2)})`
627
+ };
628
+ }
629
+ },
630
+ depends_on: {
631
+ direction: "incoming",
632
+ handler: (source, target, _weight, metadata) => {
633
+ if (metadata.conditionalA && metadata.conditionalNotA) {
634
+ return {
635
+ opinion: conditionalDeduction(
636
+ source,
637
+ metadata.conditionalA,
638
+ metadata.conditionalNotA,
639
+ target.a
640
+ ),
641
+ operator: "conditional_deduction",
642
+ rationale: `Conditional deduction: prerequisite at ${project(
643
+ source
644
+ ).toFixed(2)}`
645
+ };
646
+ }
647
+ return dampedDependencyCascade(
648
+ source,
649
+ target,
650
+ metadata.propagation ?? "continuous"
651
+ );
652
+ }
653
+ },
654
+ derived_from: {
655
+ direction: "incoming",
656
+ handler: (_source, target) => ({
657
+ opinion: target,
658
+ operator: "trust_discount",
659
+ rationale: "Provenance edge \u2014 no confidence propagation"
660
+ })
661
+ },
662
+ contains: {
663
+ direction: "outgoing",
664
+ handler: (_source, target) => ({
665
+ opinion: target,
666
+ operator: "trust_discount",
667
+ rationale: "Containment edge \u2014 no confidence propagation"
668
+ })
669
+ },
670
+ tests: {
671
+ direction: "outgoing",
672
+ handler: (_source, target) => ({
673
+ opinion: target,
674
+ operator: "trust_discount",
675
+ rationale: "Testing edge \u2014 no confidence propagation"
676
+ })
677
+ }
678
+ };
679
+ var PROPAGATION_TRAVERSAL_SPECS = Object.entries(EDGE_PROPAGATION_RULES).map(([edgeType, rule]) => ({
680
+ edgeType,
681
+ direction: rule.direction
682
+ }));
683
+ function isPropagationEdgeType(edgeType) {
684
+ return edgeType in EDGE_PROPAGATION_RULES;
685
+ }
686
+ function getPropagationTraversalSpecs() {
687
+ return PROPAGATION_TRAVERSAL_SPECS;
688
+ }
689
+ function propagateThroughEdge(sourceOpinion, targetOpinion, edgeType, weight = 1, metadata = {}) {
690
+ const handler = isPropagationEdgeType(edgeType) ? EDGE_PROPAGATION_RULES[edgeType].handler : void 0;
691
+ if (!handler) {
692
+ return {
693
+ opinion: targetOpinion,
694
+ operator: "manual_assessment",
695
+ rationale: `Unknown edge type: ${edgeType} \u2014 no propagation`
696
+ };
697
+ }
698
+ return handler(sourceOpinion, targetOpinion, weight, metadata);
699
+ }
700
+ function propagateAllEdges(currentOpinion, incomingEdges) {
701
+ let result = currentOpinion;
702
+ const rationales = [];
703
+ for (const edgeType of ["depends_on", "informs", "supports"]) {
704
+ for (const incoming of incomingEdges.filter((edge) => edge.edgeType === edgeType)) {
705
+ const propagated = propagateThroughEdge(
706
+ incoming.sourceOpinion,
707
+ result,
708
+ incoming.edgeType,
709
+ incoming.weight,
710
+ incoming.metadata
711
+ );
712
+ result = propagated.opinion;
713
+ rationales.push(propagated.rationale);
714
+ }
715
+ }
716
+ return {
717
+ opinion: result,
718
+ operator: "cumulative_fusion",
719
+ rationale: rationales.join("; ")
720
+ };
721
+ }
722
+
723
+ // src/v1/operations/dynamics/revision.ts
724
+ function clamp013(value) {
725
+ return Math.max(0, Math.min(1, value));
726
+ }
727
+ function toEvidence(probability, weight) {
728
+ const safeProbability = clamp013(probability);
729
+ const safeWeight = Number.isFinite(weight) ? Math.max(0, weight) : 0;
730
+ return {
731
+ alpha: safeProbability * safeWeight,
732
+ beta: (1 - safeProbability) * safeWeight
733
+ };
734
+ }
735
+ function bayesianUpdate(priorConfidence, priorWeight, newAssessment, newWeight, options) {
736
+ return reviseConfidence({
737
+ priorConfidence,
738
+ priorWeight,
739
+ newAssessment,
740
+ newWeight,
741
+ baseRate: options?.baseRate,
742
+ nonInformativeWeight: options?.nonInformativeWeight
743
+ });
744
+ }
745
+ function reviseConfidence(args) {
746
+ return project(reviseConfidenceOpinion(args));
747
+ }
748
+ function reviseConfidenceOpinion(args) {
749
+ const priorEvidence = toEvidence(args.priorConfidence, args.priorWeight);
750
+ const newEvidence = toEvidence(args.newAssessment, args.newWeight ?? 1);
751
+ return opinionFromBeta(
752
+ priorEvidence.alpha + newEvidence.alpha,
753
+ priorEvidence.beta + newEvidence.beta,
754
+ args.nonInformativeWeight ?? DEFAULT_NON_INFORMATIVE_WEIGHT,
755
+ args.baseRate ?? 0.5
756
+ );
757
+ }
758
+
759
+ // src/v1/operations/dynamics/decay.ts
760
+ var DECAY_TIERS = {
761
+ FRESH: {
762
+ maxAgeDays: 30,
763
+ weight: 1,
764
+ label: "fresh",
765
+ action: "Full confidence \u2014 recently validated",
766
+ rescoreInDays: 30
767
+ },
768
+ AGING: {
769
+ maxAgeDays: 90,
770
+ weight: 0.8,
771
+ label: "aging",
772
+ action: "Evidence refresh recommended",
773
+ rescoreInDays: 14
774
+ },
775
+ STALE: {
776
+ maxAgeDays: 180,
777
+ weight: 0.5,
778
+ label: "stale",
779
+ action: "Evidence update required before trusting",
780
+ rescoreInDays: 7
781
+ },
782
+ EXPIRED: {
783
+ maxAgeDays: Number.POSITIVE_INFINITY,
784
+ weight: 0.2,
785
+ label: "expired",
786
+ action: "Full re-evaluation needed",
787
+ rescoreInDays: 0
788
+ }
789
+ };
790
+ var DEADLINE_URGENCY = {
791
+ DISTANT: {
792
+ minDaysToDeadline: 365,
793
+ urgencyMultiplier: 1,
794
+ label: "distant",
795
+ rescoreIntervalDays: 90,
796
+ action: "Quarterly confidence check"
797
+ },
798
+ APPROACHING: {
799
+ minDaysToDeadline: 180,
800
+ urgencyMultiplier: 0.9,
801
+ label: "approaching",
802
+ rescoreIntervalDays: 30,
803
+ action: "Monthly confidence check \u2014 conditions may be shifting"
804
+ },
805
+ NEAR: {
806
+ minDaysToDeadline: 90,
807
+ urgencyMultiplier: 0.75,
808
+ label: "near",
809
+ rescoreIntervalDays: 14,
810
+ action: "Biweekly rescore \u2014 deadline within 3 months"
811
+ },
812
+ IMMINENT: {
813
+ minDaysToDeadline: 30,
814
+ urgencyMultiplier: 0.6,
815
+ label: "imminent",
816
+ rescoreIntervalDays: 7,
817
+ action: "Weekly rescore \u2014 deadline within 1 month"
818
+ },
819
+ CRITICAL: {
820
+ minDaysToDeadline: 7,
821
+ urgencyMultiplier: 0.4,
822
+ label: "critical",
823
+ rescoreIntervalDays: 1,
824
+ action: "Daily rescore \u2014 deadline THIS WEEK"
825
+ },
826
+ OVERDUE: {
827
+ minDaysToDeadline: Number.NEGATIVE_INFINITY,
828
+ urgencyMultiplier: 0.2,
829
+ label: "overdue",
830
+ rescoreIntervalDays: 0,
831
+ action: "OVERDUE \u2014 must validate or archive immediately"
832
+ }
833
+ };
834
+ function normalizeBeliefConfidence(confidence) {
835
+ if (typeof confidence !== "number" || !Number.isFinite(confidence)) {
836
+ return null;
837
+ }
838
+ if (confidence >= 0 && confidence <= 1) {
839
+ return confidence;
840
+ }
841
+ if (confidence > 1 && confidence <= 100) {
842
+ return confidence / 100;
843
+ }
844
+ return null;
845
+ }
846
+ function hasResolvedPredictionOutcome(predictionMeta) {
847
+ if (!predictionMeta || typeof predictionMeta !== "object") {
848
+ return false;
849
+ }
850
+ const outcome = predictionMeta.outcome;
851
+ return outcome === "confirmed" || outcome === "disconfirmed" || outcome === "partial" || outcome === "expired";
852
+ }
853
+ function resolveLifecycleBucket(args) {
854
+ if (normalizeBeliefConfidence(args.confidence) === 0 || normalizeBeliefConfidence(args.confidence) === 1 || hasResolvedPredictionOutcome(args.predictionMeta)) {
855
+ return "fact";
856
+ }
857
+ if (args.beliefStatus === "assumption" || args.beliefStatus === "hypothesis" || args.beliefStatus === "belief" || args.beliefStatus === "fact") {
858
+ if (normalizeBeliefConfidence(args.confidence) !== null && (args.beliefStatus === "assumption" || args.beliefStatus === "hypothesis")) {
859
+ return "belief";
860
+ }
861
+ return args.beliefStatus;
862
+ }
863
+ return "assumption";
864
+ }
865
+ function lifecycleMultiplier(status) {
866
+ if (status === "assumption") {
867
+ return 0.65;
868
+ }
869
+ if (status === "hypothesis") {
870
+ return 0.8;
871
+ }
872
+ return 1;
873
+ }
874
+ function computeBaseDecay(lastScoredAt) {
875
+ const ageDays = (Date.now() - lastScoredAt) / (1e3 * 60 * 60 * 24);
876
+ let tier = DECAY_TIERS.EXPIRED;
877
+ if (ageDays <= DECAY_TIERS.FRESH.maxAgeDays) {
878
+ tier = DECAY_TIERS.FRESH;
879
+ } else if (ageDays <= DECAY_TIERS.AGING.maxAgeDays) {
880
+ tier = DECAY_TIERS.AGING;
881
+ } else if (ageDays <= DECAY_TIERS.STALE.maxAgeDays) {
882
+ tier = DECAY_TIERS.STALE;
883
+ }
884
+ return { ageDays, tier, weight: tier.weight };
885
+ }
886
+ function computeDeadlineUrgency(expectedBy) {
887
+ if (!expectedBy) {
888
+ return null;
889
+ }
890
+ const daysToDeadline = (expectedBy - Date.now()) / (1e3 * 60 * 60 * 24);
891
+ let urgencyTier = DEADLINE_URGENCY.DISTANT;
892
+ if (daysToDeadline < 0) {
893
+ urgencyTier = DEADLINE_URGENCY.OVERDUE;
894
+ } else if (daysToDeadline <= 7) {
895
+ urgencyTier = DEADLINE_URGENCY.CRITICAL;
896
+ } else if (daysToDeadline <= 30) {
897
+ urgencyTier = DEADLINE_URGENCY.IMMINENT;
898
+ } else if (daysToDeadline <= 90) {
899
+ urgencyTier = DEADLINE_URGENCY.NEAR;
900
+ } else if (daysToDeadline <= 180) {
901
+ urgencyTier = DEADLINE_URGENCY.APPROACHING;
902
+ }
903
+ return {
904
+ daysToDeadline: Math.round(daysToDeadline),
905
+ urgencyTier,
906
+ urgencyMultiplier: urgencyTier.urgencyMultiplier,
907
+ isOverdue: daysToDeadline < 0
908
+ };
909
+ }
910
+ function computeEffectiveDecay(lastScoredAt, expectedBy, beliefStatus) {
911
+ const base = computeBaseDecay(lastScoredAt);
912
+ const urgency = computeDeadlineUrgency(expectedBy);
913
+ const effectiveWeight = (urgency ? base.weight * urgency.urgencyMultiplier : base.weight) * lifecycleMultiplier(beliefStatus);
914
+ const urgencyRescoreDays = urgency?.urgencyTier.rescoreIntervalDays ?? Number.POSITIVE_INFINITY;
915
+ const rescoreInDays = Math.min(base.tier.rescoreInDays, urgencyRescoreDays);
916
+ const rescoreByDate = lastScoredAt + rescoreInDays * 24 * 60 * 60 * 1e3;
917
+ let action = base.tier.action;
918
+ if (urgency && urgency.urgencyTier.label !== "distant") {
919
+ action = `${urgency.urgencyTier.action}. ${base.tier.action}`;
920
+ }
921
+ return {
922
+ ageDays: base.ageDays,
923
+ baseTier: base.tier,
924
+ baseWeight: base.weight,
925
+ urgency,
926
+ effectiveWeight: Math.max(0, Math.min(1, effectiveWeight)),
927
+ rescoreByDate,
928
+ rescoreInDays,
929
+ action
930
+ };
931
+ }
932
+ function getRescoringSchedule(opts) {
933
+ const lifecycleStatus = resolveLifecycleBucket({
934
+ beliefStatus: opts.beliefStatus,
935
+ confidence: opts.confidence,
936
+ predictionMeta: opts.predictionMeta
937
+ });
938
+ const decayState = computeEffectiveDecay(
939
+ opts.lastScoredAt,
940
+ opts.expectedBy,
941
+ lifecycleStatus
942
+ );
943
+ const daysUntilRescore = (decayState.rescoreByDate - Date.now()) / (1e3 * 60 * 60 * 24);
944
+ const isOverdue = daysUntilRescore < 0;
945
+ let priority;
946
+ let reason;
947
+ if (isOverdue && lifecycleStatus === "assumption") {
948
+ priority = "critical";
949
+ reason = `Untested assumption is stale (${Math.round(decayState.ageDays)}d) \u2014 validate or supersede`;
950
+ } else if (isOverdue && lifecycleStatus === "hypothesis" || lifecycleStatus === "hypothesis" && daysUntilRescore < 7) {
951
+ priority = "high";
952
+ reason = `Hypothesis aging without validation (${Math.round(decayState.ageDays)}d) \u2014 run/finish sprint testing`;
953
+ } else if (decayState.urgency?.isOverdue) {
954
+ priority = "critical";
955
+ reason = `Prediction deadline passed ${Math.abs(decayState.urgency.daysToDeadline)}d ago \u2014 validate or archive`;
956
+ } else if (isOverdue && decayState.baseTier.label === "expired") {
957
+ priority = "critical";
958
+ reason = `Not scored in ${Math.round(decayState.ageDays)}d \u2014 confidence severely degraded`;
959
+ } else if (isOverdue && decayState.baseTier.label === "stale") {
960
+ priority = "high";
961
+ reason = `Stale (${Math.round(decayState.ageDays)}d since scoring) \u2014 evidence update required`;
962
+ } else if (decayState.urgency && decayState.urgency.urgencyTier.label === "critical") {
963
+ priority = "critical";
964
+ reason = `Deadline in ${decayState.urgency.daysToDeadline}d \u2014 needs immediate rescoring`;
965
+ } else if (decayState.urgency && decayState.urgency.urgencyTier.label === "imminent") {
966
+ priority = "high";
967
+ reason = `Deadline in ${decayState.urgency.daysToDeadline}d \u2014 weekly rescoring required`;
968
+ } else if (isOverdue) {
969
+ priority = "high";
970
+ reason = `Rescore overdue by ${Math.abs(Math.round(daysUntilRescore))}d`;
971
+ } else if (opts.temporalNature === "forecast" && daysUntilRescore < 7) {
972
+ priority = "medium";
973
+ reason = `Forecast belief \u2014 next rescore due in ${Math.round(daysUntilRescore)}d`;
974
+ } else if (daysUntilRescore < 14) {
975
+ priority = "medium";
976
+ reason = `Rescore due in ${Math.round(daysUntilRescore)}d`;
977
+ } else {
978
+ priority = "low";
979
+ reason = `On schedule \u2014 next rescore in ${Math.round(daysUntilRescore)}d`;
980
+ }
981
+ if ((opts.confidence ?? 0) >= 0.8 && decayState.baseTier.label !== "fresh" && priority === "medium") {
982
+ priority = "high";
983
+ reason = `High-confidence belief (${((opts.confidence ?? 0) * 100).toFixed(0)}%) aging without rescore \u2014 ${reason}`;
984
+ }
985
+ return {
986
+ nextRescoreBy: decayState.rescoreByDate,
987
+ daysUntilRescore: Math.round(daysUntilRescore),
988
+ isOverdue,
989
+ priority,
990
+ reason,
991
+ decay: decayState
992
+ };
993
+ }
994
+ function decay(current, daysSinceLastUpdate, halfLifeDays = 90) {
995
+ if (daysSinceLastUpdate <= 0) {
996
+ return current;
997
+ }
998
+ const decayFactor = Math.pow(0.5, daysSinceLastUpdate / halfLifeDays);
999
+ const certainty = current.b + current.d;
1000
+ const lostCertainty = certainty - certainty * decayFactor;
1001
+ return opinion(
1002
+ current.b * decayFactor,
1003
+ current.d * decayFactor,
1004
+ current.u + lostCertainty,
1005
+ current.a
1006
+ );
1007
+ }
1008
+
1009
+ // src/v1/operations/contracts/epistemicContract.ts
1010
+ var BUILT_IN_EVIDENTIAL_EVALUATOR = "evidential";
1011
+ var BUILT_IN_EVIDENTIAL_ALIASES = /* @__PURE__ */ new Set([
1012
+ BUILT_IN_EVIDENTIAL_EVALUATOR,
1013
+ "built_in_evidential",
1014
+ "builtin_evidential"
1015
+ ]);
1016
+ var BUILT_IN_METRIC_CHECKER = "metric_checker";
1017
+ var BUILT_IN_REFERENCE_CHECK_COUNTER = "reference_check_counter";
1018
+ var BUILT_IN_TEMPORAL_DEADLINE = "temporal_deadline";
1019
+ var BUILT_IN_MARKET_INDEX_COMPARATOR = "market_index_comparator";
1020
+ function clampConfidence(value) {
1021
+ return Math.max(0, Math.min(1, value));
1022
+ }
1023
+ function generateContractId() {
1024
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
1025
+ return crypto.randomUUID();
1026
+ }
1027
+ return `contract-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
1028
+ }
1029
+ function deriveContractStatus(result, currentStatus) {
1030
+ if (currentStatus === "archived") {
1031
+ return currentStatus;
1032
+ }
1033
+ switch (result) {
1034
+ case "confirmed":
1035
+ return "satisfied";
1036
+ case "disconfirmed":
1037
+ return "violated";
1038
+ case "expired":
1039
+ return "expired";
1040
+ default:
1041
+ return currentStatus === "satisfied" || currentStatus === "violated" || currentStatus === "expired" ? "active" : currentStatus;
1042
+ }
1043
+ }
1044
+ function deriveVerificationTrigger(result) {
1045
+ switch (result) {
1046
+ case "confirmed":
1047
+ return "verification_confirmed";
1048
+ case "disconfirmed":
1049
+ return "verification_disconfirmed";
1050
+ case "expired":
1051
+ return "verification_expired";
1052
+ case "partial":
1053
+ return "verification_partial";
1054
+ default:
1055
+ return null;
1056
+ }
1057
+ }
1058
+ function deriveContractModulationPlan(args) {
1059
+ const trigger = deriveVerificationTrigger(args.result);
1060
+ if (!trigger) {
1061
+ return null;
1062
+ }
1063
+ if (args.result === "confirmed") {
1064
+ const rawNext = args.currentConfidence + args.modulation.onConfirmed.delta;
1065
+ const confidenceAfter = clampConfidence(
1066
+ Math.min(
1067
+ args.modulation.onConfirmed.ceiling ?? Number.POSITIVE_INFINITY,
1068
+ rawNext
1069
+ )
1070
+ );
1071
+ return {
1072
+ trigger,
1073
+ confidenceBefore: args.currentConfidence,
1074
+ confidenceAfter,
1075
+ confidenceDelta: confidenceAfter - args.currentConfidence
1076
+ };
1077
+ }
1078
+ if (args.result === "disconfirmed") {
1079
+ const rawNext = args.currentConfidence + args.modulation.onDisconfirmed.delta;
1080
+ const confidenceAfter = clampConfidence(
1081
+ Math.max(args.modulation.onDisconfirmed.floor ?? 0, rawNext)
1082
+ );
1083
+ return {
1084
+ trigger,
1085
+ confidenceBefore: args.currentConfidence,
1086
+ confidenceAfter,
1087
+ confidenceDelta: confidenceAfter - args.currentConfidence
1088
+ };
1089
+ }
1090
+ if (args.result === "expired" && args.modulation.onExpired) {
1091
+ const confidenceAfter = clampConfidence(
1092
+ args.currentConfidence + args.modulation.onExpired.delta
1093
+ );
1094
+ return {
1095
+ trigger,
1096
+ confidenceBefore: args.currentConfidence,
1097
+ confidenceAfter,
1098
+ confidenceDelta: confidenceAfter - args.currentConfidence
1099
+ };
1100
+ }
1101
+ if (args.result === "partial" && args.modulation.onPartial) {
1102
+ if ((args.resultConfidence ?? 0) < args.modulation.onPartial.threshold) {
1103
+ return null;
1104
+ }
1105
+ const confidenceAfter = clampConfidence(
1106
+ args.currentConfidence + args.modulation.onPartial.delta
1107
+ );
1108
+ return {
1109
+ trigger,
1110
+ confidenceBefore: args.currentConfidence,
1111
+ confidenceAfter,
1112
+ confidenceDelta: confidenceAfter - args.currentConfidence
1113
+ };
1114
+ }
1115
+ return null;
1116
+ }
1117
+ function createInheritedContractRecord(contract, args) {
1118
+ return {
1119
+ beliefNodeId: args.beliefNodeId,
1120
+ contractId: generateContractId(),
1121
+ title: contract.title,
1122
+ description: contract.description,
1123
+ conditionType: contract.conditionType,
1124
+ direction: contract.direction,
1125
+ condition: contract.condition,
1126
+ deadline: contract.deadline,
1127
+ compositeOf: contract.compositeOf,
1128
+ compositeOperator: contract.compositeOperator,
1129
+ modulation: contract.modulation,
1130
+ evaluationSchedule: contract.evaluationSchedule,
1131
+ periodicIntervalMs: contract.periodicIntervalMs,
1132
+ status: "active",
1133
+ lineageSource: "inherited",
1134
+ inheritedFromContractId: contract.contractId,
1135
+ inheritedFromBeliefNodeId: contract.beliefNodeId,
1136
+ inheritedAt: args.now,
1137
+ topicId: args.topicId,
1138
+ createdAt: args.now,
1139
+ createdBy: args.createdBy,
1140
+ updatedAt: args.now
1141
+ };
1142
+ }
1143
+ function normalizeEvidentialAction(value) {
1144
+ return value === "modulate_confidence" || value === "flag_review" || value === "archive" ? value : void 0;
1145
+ }
1146
+ function parseComparisonOperator(value, evaluatorName) {
1147
+ if (value === "gte" || value === "lte" || value === "eq" || value === "gt" || value === "lt") {
1148
+ return value;
1149
+ }
1150
+ throw new Error(
1151
+ `${evaluatorName} requires operator to be one of gte, lte, eq, gt, or lt.`
1152
+ );
1153
+ }
1154
+ function parseNumericThreshold(value, evaluatorName) {
1155
+ if (typeof value === "number" && Number.isFinite(value)) {
1156
+ return value;
1157
+ }
1158
+ throw new Error(`${evaluatorName} requires a finite numeric threshold.`);
1159
+ }
1160
+ function pickFiniteNumber(config, keys) {
1161
+ for (const key of keys) {
1162
+ const value = config[key];
1163
+ if (typeof value === "number" && Number.isFinite(value)) {
1164
+ return value;
1165
+ }
1166
+ }
1167
+ return void 0;
1168
+ }
1169
+ function getEvaluatorInputRecord(inputData, nestedKey) {
1170
+ if (!inputData || typeof inputData !== "object") {
1171
+ return {};
1172
+ }
1173
+ const root = inputData;
1174
+ const nested = root[nestedKey];
1175
+ if (nested && typeof nested === "object") {
1176
+ return nested;
1177
+ }
1178
+ return root;
1179
+ }
1180
+ function parseEvidentialEvaluatorConfig(value) {
1181
+ if (!value || typeof value !== "object") {
1182
+ throw new Error(
1183
+ "Evidential contracts require condition.evaluatorConfig with metric/operator/threshold."
1184
+ );
1185
+ }
1186
+ const config = value;
1187
+ const metric = config.metric;
1188
+ const operator = config.operator;
1189
+ const threshold = config.threshold;
1190
+ if (metric !== "evidence_count" && metric !== "contradiction_status" && metric !== "edge_freshness" && metric !== "dependent_count") {
1191
+ throw new Error(`Unsupported evidential metric: ${String(metric)}`);
1192
+ }
1193
+ if (operator !== "gte" && operator !== "lte" && operator !== "eq" && operator !== "gt" && operator !== "lt") {
1194
+ throw new Error(`Unsupported evidential operator: ${String(operator)}`);
1195
+ }
1196
+ if (typeof threshold !== "number" || !Number.isFinite(threshold)) {
1197
+ throw new Error("Evidential contracts require a numeric threshold.");
1198
+ }
1199
+ const actionParams = config.actionParams && typeof config.actionParams === "object" && config.actionParams !== null ? config.actionParams : void 0;
1200
+ return {
1201
+ metric,
1202
+ operator,
1203
+ threshold,
1204
+ action: normalizeEvidentialAction(config.action),
1205
+ actionParams: actionParams && (typeof actionParams.targetConfidence === "number" || typeof actionParams.rationale === "string") ? {
1206
+ targetConfidence: typeof actionParams.targetConfidence === "number" ? actionParams.targetConfidence : void 0,
1207
+ rationale: typeof actionParams.rationale === "string" ? actionParams.rationale : void 0
1208
+ } : void 0
1209
+ };
1210
+ }
1211
+ function compareMetricValue(operator, left, right) {
1212
+ switch (operator) {
1213
+ case "gte":
1214
+ return left >= right;
1215
+ case "lte":
1216
+ return left <= right;
1217
+ case "eq":
1218
+ return left === right;
1219
+ case "gt":
1220
+ return left > right;
1221
+ case "lt":
1222
+ return left < right;
1223
+ default:
1224
+ return false;
1225
+ }
1226
+ }
1227
+ function resolveComparisonResult(direction, comparisonSatisfied) {
1228
+ return direction === "falsifies" ? comparisonSatisfied ? "disconfirmed" : "confirmed" : comparisonSatisfied ? "confirmed" : "disconfirmed";
1229
+ }
1230
+ function buildComparisonRationale(args) {
1231
+ const renderedObserved = args.observedValue === null ? "no data" : `${args.observedValue}${args.unit ? ` ${args.unit}` : ""}`;
1232
+ const renderedThreshold = `${args.threshold}${args.unit ? ` ${args.unit}` : ""}`;
1233
+ const clause = `${args.label} observed ${renderedObserved} against ${args.operator} ${renderedThreshold}`;
1234
+ if (args.observedValue === null) {
1235
+ return `${clause}; evaluator returned ${args.result} because no current data was available.`;
1236
+ }
1237
+ return `${clause}; comparison ${args.comparisonSatisfied ? "passed" : "failed"}, resulting in ${args.result}.`;
1238
+ }
1239
+ function buildEvidentialRationale(args) {
1240
+ const observed = args.snapshot.value === null ? "no data" : String(args.snapshot.value);
1241
+ const clause = `${args.snapshot.metric} observed ${observed} against ${args.config.operator} ${args.config.threshold}`;
1242
+ if (args.snapshot.value === null) {
1243
+ return `${clause}; evidential evaluator treated the comparison as unmet, resulting in ${args.result}.`;
1244
+ }
1245
+ return `${clause}; comparison ${args.comparisonSatisfied ? "passed" : "failed"}, resulting in ${args.result}.`;
1246
+ }
1247
+ function parseMetricCheckerConfig(value) {
1248
+ if (!value || typeof value !== "object") {
1249
+ throw new Error(
1250
+ "metric_checker requires condition.evaluatorConfig with observedValue/operator/threshold."
1251
+ );
1252
+ }
1253
+ const config = value;
1254
+ return {
1255
+ metric: typeof config.metric === "string" && config.metric.length > 0 ? config.metric : void 0,
1256
+ operator: parseComparisonOperator(config.operator, BUILT_IN_METRIC_CHECKER),
1257
+ threshold: parseNumericThreshold(config.threshold, BUILT_IN_METRIC_CHECKER),
1258
+ observedValue: pickFiniteNumber(config, ["observedValue", "value"]),
1259
+ currentValue: pickFiniteNumber(config, ["currentValue"]),
1260
+ metricValue: pickFiniteNumber(config, ["metricValue"]),
1261
+ unit: typeof config.unit === "string" && config.unit.length > 0 ? config.unit : void 0
1262
+ };
1263
+ }
1264
+ function parseReferenceCheckCounterConfig(value) {
1265
+ if (!value || typeof value !== "object") {
1266
+ throw new Error(
1267
+ "reference_check_counter requires condition.evaluatorConfig with tag/operator/threshold."
1268
+ );
1269
+ }
1270
+ const config = value;
1271
+ if (typeof config.tag !== "string" || config.tag.trim().length === 0) {
1272
+ throw new Error("reference_check_counter requires a non-empty tag.");
1273
+ }
1274
+ return {
1275
+ tag: config.tag.trim(),
1276
+ operator: parseComparisonOperator(
1277
+ config.operator,
1278
+ BUILT_IN_REFERENCE_CHECK_COUNTER
1279
+ ),
1280
+ threshold: parseNumericThreshold(
1281
+ config.threshold,
1282
+ BUILT_IN_REFERENCE_CHECK_COUNTER
1283
+ ),
1284
+ caseSensitive: config.caseSensitive === true
1285
+ };
1286
+ }
1287
+ function parseTemporalDeadlineConfig(value) {
1288
+ if (!value || typeof value !== "object") {
1289
+ return {};
1290
+ }
1291
+ const config = value;
1292
+ return {
1293
+ label: typeof config.label === "string" && config.label.length > 0 ? config.label : void 0,
1294
+ completed: config.completed === true,
1295
+ completedAt: pickFiniteNumber(config, ["completedAt"]),
1296
+ observedAt: pickFiniteNumber(config, ["observedAt"]),
1297
+ satisfiedAt: pickFiniteNumber(config, ["satisfiedAt"]),
1298
+ achievedAt: pickFiniteNumber(config, ["achievedAt"])
1299
+ };
1300
+ }
1301
+ function parseMarketIndexComparatorConfig(value) {
1302
+ if (!value || typeof value !== "object") {
1303
+ throw new Error(
1304
+ "market_index_comparator requires condition.evaluatorConfig with subjectValue/benchmarkValue/operator/threshold."
1305
+ );
1306
+ }
1307
+ const config = value;
1308
+ return {
1309
+ subject: typeof config.subject === "string" && config.subject.length > 0 ? config.subject : void 0,
1310
+ subjectValue: pickFiniteNumber(config, ["subjectValue", "leftValue"]),
1311
+ primaryValue: pickFiniteNumber(config, ["primaryValue"]),
1312
+ benchmark: typeof config.benchmark === "string" && config.benchmark.length > 0 ? config.benchmark : void 0,
1313
+ benchmarkValue: pickFiniteNumber(config, ["benchmarkValue", "rightValue"]),
1314
+ comparisonValue: pickFiniteNumber(config, ["comparisonValue"]),
1315
+ operator: parseComparisonOperator(
1316
+ config.operator,
1317
+ BUILT_IN_MARKET_INDEX_COMPARATOR
1318
+ ),
1319
+ threshold: parseNumericThreshold(
1320
+ config.threshold,
1321
+ BUILT_IN_MARKET_INDEX_COMPARATOR
1322
+ )
1323
+ };
1324
+ }
1325
+
1326
+ // src/v1/operations/approximation.ts
1327
+ var SL_APPROXIMATION_OPERATOR_NAMES = [
1328
+ "cumulativeFusion",
1329
+ "averagingFusion",
1330
+ "conditionalAbduction",
1331
+ "opinionFromDirichlet",
1332
+ "projectDirichletOpinion",
1333
+ "opinionFromBeta",
1334
+ "betaFromOpinion",
1335
+ "dampedDependencyOpinion",
1336
+ "dampedDependencyCascade"
1337
+ ];
1338
+
1339
+ // src/v1/operations/canonical.ts
1340
+ var SL_CANONICAL_OPERATOR_NAMES = [
1341
+ "opinion",
1342
+ "vacuous",
1343
+ "dogmatic",
1344
+ "project",
1345
+ "trustDiscount",
1346
+ "negate",
1347
+ "conditionalDeduction",
1348
+ "confidenceFromOpinion",
1349
+ "confidenceFromSL",
1350
+ "opinionFromBaseRate",
1351
+ "opinionFromDogmatic",
1352
+ "opinionFromProjected"
1353
+ ];
1354
+
1355
+ // src/v1/operations/lucern.ts
1356
+ var LUCERN_SPECIFIC_OPERATOR_NAMES = [
1357
+ "clamp01",
1358
+ "toStoredOpinionFields",
1359
+ "readOpinionFromRecord",
1360
+ "opinionFromScalar",
1361
+ "temporalDecay",
1362
+ "toDogmaticOpinion",
1363
+ "hasProjectedOpinionChanged",
1364
+ "normalizeTupleContradictionPolicy",
1365
+ "detectTupleContradiction",
1366
+ "evaluateTupleContradictionTransition",
1367
+ "confidenceLevel",
1368
+ "constraintFusion",
1369
+ "evidenceBalance",
1370
+ "areTensioned",
1371
+ "informationGain",
1372
+ "isPropagationEdgeType",
1373
+ "getPropagationTraversalSpecs",
1374
+ "propagateThroughEdge",
1375
+ "propagateAllEdges",
1376
+ "bayesianUpdate",
1377
+ "reviseConfidence",
1378
+ "computeBaseDecay",
1379
+ "computeDeadlineUrgency",
1380
+ "computeEffectiveDecay",
1381
+ "getRescoringSchedule",
1382
+ "decay",
1383
+ "applyNegativeSupport",
1384
+ "applyNegativeEvidence",
1385
+ "deriveContractStatus",
1386
+ "deriveVerificationTrigger",
1387
+ "deriveContractModulationPlan",
1388
+ "createInheritedContractRecord",
1389
+ "normalizeEvidentialAction",
1390
+ "parseComparisonOperator",
1391
+ "parseNumericThreshold",
1392
+ "pickFiniteNumber",
1393
+ "getEvaluatorInputRecord",
1394
+ "parseEvidentialEvaluatorConfig",
1395
+ "compareMetricValue",
1396
+ "resolveComparisonResult",
1397
+ "buildComparisonRationale",
1398
+ "buildEvidentialRationale",
1399
+ "parseMetricCheckerConfig",
1400
+ "parseReferenceCheckCounterConfig",
1401
+ "parseTemporalDeadlineConfig",
1402
+ "parseMarketIndexComparatorConfig"
1403
+ ];
1404
+
1405
+ // src/v1/operations/operatorTaxonomy.ts
1406
+ var OPERATOR_TAXONOMY_TAGS = [
1407
+ "SL_CANONICAL",
1408
+ "SL_APPROXIMATION",
1409
+ "LUCERN_SPECIFIC"
1410
+ ];
1411
+ var PUBLIC_OPERATOR_EXPORT_NAMES = [
1412
+ ...SL_CANONICAL_OPERATOR_NAMES,
1413
+ ...SL_APPROXIMATION_OPERATOR_NAMES,
1414
+ ...LUCERN_SPECIFIC_OPERATOR_NAMES
1415
+ ];
1416
+ var OPERATOR_TAXONOMY_ENTRIES = [
1417
+ {
1418
+ operator: "opinion",
1419
+ tag: "SL_CANONICAL",
1420
+ sourceModule: "operations/subjectiveLogic/index.ts",
1421
+ rationale: "Constructs the canonical binomial SL opinion tuple and normalizes it into valid mass components."
1422
+ },
1423
+ {
1424
+ operator: "vacuous",
1425
+ tag: "SL_CANONICAL",
1426
+ sourceModule: "operations/subjectiveLogic/index.ts",
1427
+ rationale: "Builds the canonical vacuous opinion with full uncertainty and an explicit base rate."
1428
+ },
1429
+ {
1430
+ operator: "dogmatic",
1431
+ tag: "SL_CANONICAL",
1432
+ sourceModule: "operations/subjectiveLogic/index.ts",
1433
+ rationale: "Builds the canonical dogmatic opinion with zero uncertainty at a projected probability."
1434
+ },
1435
+ {
1436
+ operator: "project",
1437
+ tag: "SL_CANONICAL",
1438
+ sourceModule: "operations/subjectiveLogic/index.ts",
1439
+ rationale: "Implements the canonical SL projected probability formula P = b + a*u."
1440
+ },
1441
+ {
1442
+ operator: "trustDiscount",
1443
+ tag: "SL_CANONICAL",
1444
+ sourceModule: "operations/subjectiveLogic/index.ts",
1445
+ rationale: "Implements standard trust discounting by attenuating belief/disbelief mass and returning the remainder to uncertainty."
1446
+ },
1447
+ {
1448
+ operator: "negate",
1449
+ tag: "SL_CANONICAL",
1450
+ sourceModule: "operations/subjectiveLogic/index.ts",
1451
+ rationale: "Implements canonical opinion negation by swapping belief and disbelief and complementing the base rate."
1452
+ },
1453
+ {
1454
+ operator: "confidenceFromOpinion",
1455
+ tag: "SL_CANONICAL",
1456
+ sourceModule: "operations/scoring.ts",
1457
+ rationale: "Projects a stored opinion into its canonical scalar probability without adding Lucern-specific heuristics."
1458
+ },
1459
+ {
1460
+ operator: "confidenceFromSL",
1461
+ tag: "SL_CANONICAL",
1462
+ sourceModule: "operations/scoring.ts",
1463
+ rationale: "Thin wrapper over the canonical SL projection formula for callers that provide tuple components directly."
1464
+ },
1465
+ {
1466
+ operator: "opinionFromBaseRate",
1467
+ tag: "SL_CANONICAL",
1468
+ sourceModule: "operations/scoring.ts",
1469
+ rationale: "Constructs the canonical vacuous opinion from a prior/base-rate probability."
1470
+ },
1471
+ {
1472
+ operator: "opinionFromDogmatic",
1473
+ tag: "SL_CANONICAL",
1474
+ sourceModule: "operations/scoring.ts",
1475
+ rationale: "Constructs the canonical dogmatic opinion from a projected probability and base rate."
1476
+ },
1477
+ {
1478
+ operator: "opinionFromProjected",
1479
+ tag: "SL_CANONICAL",
1480
+ sourceModule: "operations/scoring.ts",
1481
+ rationale: "Reconstructs a valid opinion from projected probability plus explicit uncertainty without changing the SL tuple semantics."
1482
+ },
1483
+ {
1484
+ operator: "cumulativeFusion",
1485
+ tag: "SL_APPROXIMATION",
1486
+ sourceModule: "operations/subjectiveLogic/index.ts",
1487
+ rationale: "Implements the cumulative fusion family, but Lucern averages base rates and special-cases dogmatic pairs instead of claiming a verbatim textbook transcription."
1488
+ },
1489
+ {
1490
+ operator: "averagingFusion",
1491
+ tag: "SL_APPROXIMATION",
1492
+ sourceModule: "operations/subjectiveLogic/index.ts",
1493
+ rationale: "Implements the averaging fusion family with Lucern-specific base-rate averaging and dogmatic shortcuts."
1494
+ },
1495
+ {
1496
+ operator: "conditionalDeduction",
1497
+ tag: "SL_CANONICAL",
1498
+ sourceModule: "operations/subjectiveLogic/index.ts",
1499
+ rationale: "Implements textbook J\xF8sang conditional deduction over (b, d, u, a) tuples with explicit child base-rate derivation and uncertainty correction."
1500
+ },
1501
+ {
1502
+ operator: "conditionalAbduction",
1503
+ tag: "SL_APPROXIMATION",
1504
+ sourceModule: "operations/subjectiveLogic/index.ts",
1505
+ rationale: "Implements inverse conditional reasoning through projected probabilities and a Lucern uncertainty floor rather than a full subjective-network derivation."
1506
+ },
1507
+ {
1508
+ operator: "opinionFromDirichlet",
1509
+ tag: "SL_APPROXIMATION",
1510
+ sourceModule: "operations/bridge/index.ts",
1511
+ rationale: "Bridges multinomial Dirichlet-style evidence counts into opinion mass with a configurable non-informative weight and normalized base-rate vector."
1512
+ },
1513
+ {
1514
+ operator: "projectDirichletOpinion",
1515
+ tag: "SL_APPROXIMATION",
1516
+ sourceModule: "operations/bridge/index.ts",
1517
+ rationale: "Projects a Dirichlet opinion back into a multinomial probability vector rather than into Lucern's scalar node confidence."
1518
+ },
1519
+ {
1520
+ operator: "opinionFromBeta",
1521
+ tag: "SL_APPROXIMATION",
1522
+ sourceModule: "operations/bridge/index.ts",
1523
+ rationale: "Bridges Beta evidence counts into SL opinions, but exposes a configurable non-informative weight instead of locking the canonical bridge to W = 2."
1524
+ },
1525
+ {
1526
+ operator: "betaFromOpinion",
1527
+ tag: "SL_APPROXIMATION",
1528
+ sourceModule: "operations/bridge/index.ts",
1529
+ rationale: "Bridges opinions back to Beta parameters while allowing a configurable non-informative weight and explicit dogmatic infinities."
1530
+ },
1531
+ {
1532
+ operator: "dampedDependencyOpinion",
1533
+ tag: "SL_APPROXIMATION",
1534
+ sourceModule: "operations/dynamics/cascade.ts",
1535
+ rationale: "Approximates dependency propagation with a threshold-or-damping scheme instead of a general SL network inference operator. Used as the fallback when edge metadata lacks explicit conditional opinions."
1536
+ },
1537
+ {
1538
+ operator: "dampedDependencyCascade",
1539
+ tag: "SL_APPROXIMATION",
1540
+ sourceModule: "operations/dynamics/cascade.ts",
1541
+ rationale: "Wraps the damped dependency approximation and records it as dependency_cascade provenance for graph propagation. Fallback path for depends_on when edge conditionals are absent."
1542
+ },
1543
+ {
1544
+ operator: "clamp01",
1545
+ tag: "LUCERN_SPECIFIC",
1546
+ sourceModule: "operations/scoring.ts",
1547
+ rationale: "Implementation helper for Lucern APIs; it has no direct J\xF8sang operator analogue."
1548
+ },
1549
+ {
1550
+ operator: "toStoredOpinionFields",
1551
+ tag: "LUCERN_SPECIFIC",
1552
+ sourceModule: "operations/scoring.ts",
1553
+ rationale: "Serializes opinions into Lucern storage fields rather than implementing an SL algebra operator."
1554
+ },
1555
+ {
1556
+ operator: "readOpinionFromRecord",
1557
+ tag: "LUCERN_SPECIFIC",
1558
+ sourceModule: "operations/scoring.ts",
1559
+ rationale: "Deserializes opinion fields from Lucern record shapes and fallback aliases; it is storage glue, not SL."
1560
+ },
1561
+ {
1562
+ operator: "opinionFromScalar",
1563
+ tag: "LUCERN_SPECIFIC",
1564
+ sourceModule: "operations/scoring.ts",
1565
+ rationale: "Lucern convenience wrapper that multiplexes several scalar-to-opinion construction modes behind one API."
1566
+ },
1567
+ {
1568
+ operator: "temporalDecay",
1569
+ tag: "LUCERN_SPECIFIC",
1570
+ sourceModule: "operations/temporalDecay.ts",
1571
+ rationale: "Lucern temporal operator that exponentially ages evidential mass back into uncertainty while preserving the prior/base rate."
1572
+ },
1573
+ {
1574
+ operator: "toDogmaticOpinion",
1575
+ tag: "LUCERN_SPECIFIC",
1576
+ sourceModule: "operations/scoring.ts",
1577
+ rationale: "Deprecated Lucern shim retained for compatibility rather than as a canonical SL operator."
1578
+ },
1579
+ {
1580
+ operator: "hasProjectedOpinionChanged",
1581
+ tag: "LUCERN_SPECIFIC",
1582
+ sourceModule: "operations/scoring.ts",
1583
+ rationale: "Lucern propagation threshold helper that decides whether a write is materially different enough to fan out."
1584
+ },
1585
+ {
1586
+ operator: "normalizeTupleContradictionPolicy",
1587
+ tag: "LUCERN_SPECIFIC",
1588
+ sourceModule: "operations/contradiction/detectTupleContradiction.ts",
1589
+ rationale: "Normalizes Lucern tuple-contradiction thresholds; tuple contradiction is not a standard SL operator."
1590
+ },
1591
+ {
1592
+ operator: "detectTupleContradiction",
1593
+ tag: "LUCERN_SPECIFIC",
1594
+ sourceModule: "operations/contradiction/detectTupleContradiction.ts",
1595
+ rationale: "Lucern heuristic that flags simultaneous high belief and disbelief mass as a first-class contradiction state."
1596
+ },
1597
+ {
1598
+ operator: "evaluateTupleContradictionTransition",
1599
+ tag: "LUCERN_SPECIFIC",
1600
+ sourceModule: "operations/contradiction/detectTupleContradiction.ts",
1601
+ rationale: "Lucern transition helper that turns tuple-contradiction threshold crossings into workflow signals."
1602
+ },
1603
+ {
1604
+ operator: "confidenceLevel",
1605
+ tag: "LUCERN_SPECIFIC",
1606
+ sourceModule: "operations/subjectiveLogic/index.ts",
1607
+ rationale: "Buckets opinions into Lucern UI labels; it is not part of J\xF8sang's operator set."
1608
+ },
1609
+ {
1610
+ operator: "constraintFusion",
1611
+ tag: "LUCERN_SPECIFIC",
1612
+ sourceModule: "operations/subjectiveLogic/index.ts",
1613
+ rationale: "Lucern exclusivity/XOR heuristic that pressures paired opinions; there is no direct textbook SL operator with this behavior."
1614
+ },
1615
+ {
1616
+ operator: "evidenceBalance",
1617
+ tag: "LUCERN_SPECIFIC",
1618
+ sourceModule: "operations/subjectiveLogic/index.ts",
1619
+ rationale: "Lucern analytic helper that summarizes resolved evidence tilt after uncertainty is excluded."
1620
+ },
1621
+ {
1622
+ operator: "areTensioned",
1623
+ tag: "LUCERN_SPECIFIC",
1624
+ sourceModule: "operations/subjectiveLogic/index.ts",
1625
+ rationale: "Lucern heuristic for surfacing opinion tension based on projected agreement plus residual disbelief mass."
1626
+ },
1627
+ {
1628
+ operator: "informationGain",
1629
+ tag: "LUCERN_SPECIFIC",
1630
+ sourceModule: "operations/subjectiveLogic/index.ts",
1631
+ rationale: "Lucern heuristic score over uncertainty and balance; it is neither Shannon entropy nor a named SL operator."
1632
+ },
1633
+ {
1634
+ operator: "isPropagationEdgeType",
1635
+ tag: "LUCERN_SPECIFIC",
1636
+ sourceModule: "operations/dynamics/propagation.ts",
1637
+ rationale: "Lucern dispatch-table guard for graph edge semantics, not an SL algebra operator."
1638
+ },
1639
+ {
1640
+ operator: "getPropagationTraversalSpecs",
1641
+ tag: "LUCERN_SPECIFIC",
1642
+ sourceModule: "operations/dynamics/propagation.ts",
1643
+ rationale: "Exposes the pure-module edge traversal ordering used by the local propagation helpers; graph-primitives owns the multi-hop runtime."
1644
+ },
1645
+ {
1646
+ operator: "propagateThroughEdge",
1647
+ tag: "LUCERN_SPECIFIC",
1648
+ sourceModule: "operations/dynamics/propagation.ts",
1649
+ rationale: "Compiles Lucern edge types into operator application; the dispatch architecture itself has no direct J\xF8sang analogue."
1650
+ },
1651
+ {
1652
+ operator: "propagateAllEdges",
1653
+ tag: "LUCERN_SPECIFIC",
1654
+ sourceModule: "operations/dynamics/propagation.ts",
1655
+ rationale: "Lucern bounded aggregator for ordered 1-hop dispatch results across edge families."
1656
+ },
1657
+ {
1658
+ operator: "bayesianUpdate",
1659
+ tag: "LUCERN_SPECIFIC",
1660
+ sourceModule: "operations/dynamics/revision.ts",
1661
+ rationale: "Scalar Bayesian helper retained by Lucern as a fallback revision primitive outside the canonical SL operator family."
1662
+ },
1663
+ {
1664
+ operator: "reviseConfidence",
1665
+ tag: "LUCERN_SPECIFIC",
1666
+ sourceModule: "operations/dynamics/revision.ts",
1667
+ rationale: "Lucern wrapper around the scalar Bayesian revision helper rather than a direct SL operator."
1668
+ },
1669
+ {
1670
+ operator: "computeBaseDecay",
1671
+ tag: "LUCERN_SPECIFIC",
1672
+ sourceModule: "operations/dynamics/decay.ts",
1673
+ rationale: "Lucern recency heuristic over scored beliefs; decay tiers are a product rule, not part of SL."
1674
+ },
1675
+ {
1676
+ operator: "computeDeadlineUrgency",
1677
+ tag: "LUCERN_SPECIFIC",
1678
+ sourceModule: "operations/dynamics/decay.ts",
1679
+ rationale: "Lucern deadline heuristic that modulates rescoring urgency outside the SL literature."
1680
+ },
1681
+ {
1682
+ operator: "computeEffectiveDecay",
1683
+ tag: "LUCERN_SPECIFIC",
1684
+ sourceModule: "operations/dynamics/decay.ts",
1685
+ rationale: "Combines Lucern age, lifecycle, and deadline heuristics into an effective decay weight."
1686
+ },
1687
+ {
1688
+ operator: "getRescoringSchedule",
1689
+ tag: "LUCERN_SPECIFIC",
1690
+ sourceModule: "operations/dynamics/decay.ts",
1691
+ rationale: "Produces Lucern operational scheduling guidance for rescoring rather than opinion algebra."
1692
+ },
1693
+ {
1694
+ operator: "decay",
1695
+ tag: "LUCERN_SPECIFIC",
1696
+ sourceModule: "operations/dynamics/decay.ts",
1697
+ rationale: "Applies Lucern time-decay heuristics to an opinion tuple; it is not a named J\xF8sang operator."
1698
+ },
1699
+ {
1700
+ operator: "applyNegativeSupport",
1701
+ tag: "LUCERN_SPECIFIC",
1702
+ sourceModule: "operations/dynamics/defeat.ts",
1703
+ rationale: "Lucern graph-specific defeater wrapper that chooses between XOR pressure and negation-plus-discount-plus-fusion."
1704
+ },
1705
+ {
1706
+ operator: "applyNegativeEvidence",
1707
+ tag: "LUCERN_SPECIFIC",
1708
+ sourceModule: "operations/dynamics/defeat.ts",
1709
+ rationale: "Lucern signed-edge wrapper that interprets negative evidence through a composed anti-opinion path."
1710
+ },
1711
+ {
1712
+ operator: "deriveContractStatus",
1713
+ tag: "LUCERN_SPECIFIC",
1714
+ sourceModule: "operations/contracts/epistemicContract.ts",
1715
+ rationale: "Lucern contract-lifecycle helper with no direct relation to the SL operator family."
1716
+ },
1717
+ {
1718
+ operator: "deriveVerificationTrigger",
1719
+ tag: "LUCERN_SPECIFIC",
1720
+ sourceModule: "operations/contracts/epistemicContract.ts",
1721
+ rationale: "Maps Lucern contract evaluation results into confidence triggers for workflow use."
1722
+ },
1723
+ {
1724
+ operator: "deriveContractModulationPlan",
1725
+ tag: "LUCERN_SPECIFIC",
1726
+ sourceModule: "operations/contracts/epistemicContract.ts",
1727
+ rationale: "Computes Lucern confidence deltas from contract outcomes; contracts are a Lucern control surface, not SL."
1728
+ },
1729
+ {
1730
+ operator: "createInheritedContractRecord",
1731
+ tag: "LUCERN_SPECIFIC",
1732
+ sourceModule: "operations/contracts/epistemicContract.ts",
1733
+ rationale: "Builds Lucern contract lineage records rather than confidence algebra."
1734
+ },
1735
+ {
1736
+ operator: "normalizeEvidentialAction",
1737
+ tag: "LUCERN_SPECIFIC",
1738
+ sourceModule: "operations/contracts/epistemicContract.ts",
1739
+ rationale: "Normalizes Lucern evidential contract actions for workflow execution."
1740
+ },
1741
+ {
1742
+ operator: "parseComparisonOperator",
1743
+ tag: "LUCERN_SPECIFIC",
1744
+ sourceModule: "operations/contracts/epistemicContract.ts",
1745
+ rationale: "Parses Lucern contract evaluator configuration; it is not an SL operator."
1746
+ },
1747
+ {
1748
+ operator: "parseNumericThreshold",
1749
+ tag: "LUCERN_SPECIFIC",
1750
+ sourceModule: "operations/contracts/epistemicContract.ts",
1751
+ rationale: "Lucern contract-config helper for numeric thresholds."
1752
+ },
1753
+ {
1754
+ operator: "pickFiniteNumber",
1755
+ tag: "LUCERN_SPECIFIC",
1756
+ sourceModule: "operations/contracts/epistemicContract.ts",
1757
+ rationale: "Lucern parser utility for evaluator configuration and snapshots."
1758
+ },
1759
+ {
1760
+ operator: "getEvaluatorInputRecord",
1761
+ tag: "LUCERN_SPECIFIC",
1762
+ sourceModule: "operations/contracts/epistemicContract.ts",
1763
+ rationale: "Extracts Lucern evaluator payloads from nested runtime records."
1764
+ },
1765
+ {
1766
+ operator: "parseEvidentialEvaluatorConfig",
1767
+ tag: "LUCERN_SPECIFIC",
1768
+ sourceModule: "operations/contracts/epistemicContract.ts",
1769
+ rationale: "Parses Lucern evidential contract configuration into a typed evaluator plan."
1770
+ },
1771
+ {
1772
+ operator: "compareMetricValue",
1773
+ tag: "LUCERN_SPECIFIC",
1774
+ sourceModule: "operations/contracts/epistemicContract.ts",
1775
+ rationale: "Executes Lucern contract comparison semantics rather than SL tuple algebra."
1776
+ },
1777
+ {
1778
+ operator: "resolveComparisonResult",
1779
+ tag: "LUCERN_SPECIFIC",
1780
+ sourceModule: "operations/contracts/epistemicContract.ts",
1781
+ rationale: "Maps Lucern comparison outcomes into contract confirmation or disconfirmation."
1782
+ },
1783
+ {
1784
+ operator: "buildComparisonRationale",
1785
+ tag: "LUCERN_SPECIFIC",
1786
+ sourceModule: "operations/contracts/epistemicContract.ts",
1787
+ rationale: "Renders Lucern contract-evaluation explanations for auditability."
1788
+ },
1789
+ {
1790
+ operator: "buildEvidentialRationale",
1791
+ tag: "LUCERN_SPECIFIC",
1792
+ sourceModule: "operations/contracts/epistemicContract.ts",
1793
+ rationale: "Renders Lucern evidential evaluator explanations for auditability."
1794
+ },
1795
+ {
1796
+ operator: "parseMetricCheckerConfig",
1797
+ tag: "LUCERN_SPECIFIC",
1798
+ sourceModule: "operations/contracts/epistemicContract.ts",
1799
+ rationale: "Parses the Lucern metric-checker contract evaluator."
1800
+ },
1801
+ {
1802
+ operator: "parseReferenceCheckCounterConfig",
1803
+ tag: "LUCERN_SPECIFIC",
1804
+ sourceModule: "operations/contracts/epistemicContract.ts",
1805
+ rationale: "Parses the Lucern reference-check counter evaluator."
1806
+ },
1807
+ {
1808
+ operator: "parseTemporalDeadlineConfig",
1809
+ tag: "LUCERN_SPECIFIC",
1810
+ sourceModule: "operations/contracts/epistemicContract.ts",
1811
+ rationale: "Parses Lucern deadline-evaluator configuration for time-bounded claims."
1812
+ },
1813
+ {
1814
+ operator: "parseMarketIndexComparatorConfig",
1815
+ tag: "LUCERN_SPECIFIC",
1816
+ sourceModule: "operations/contracts/epistemicContract.ts",
1817
+ rationale: "Parses the Lucern market-index comparator evaluator."
1818
+ }
1819
+ ];
1820
+ var OPERATOR_TAXONOMY = Object.freeze(
1821
+ Object.fromEntries(
1822
+ OPERATOR_TAXONOMY_ENTRIES.map((entry) => [entry.operator, entry])
1823
+ )
1824
+ );
1825
+ var OPERATOR_TAXONOMY_BY_TAG = Object.freeze({
1826
+ SL_CANONICAL: SL_CANONICAL_OPERATOR_NAMES,
1827
+ SL_APPROXIMATION: SL_APPROXIMATION_OPERATOR_NAMES,
1828
+ LUCERN_SPECIFIC: LUCERN_SPECIFIC_OPERATOR_NAMES
1829
+ });
1830
+
1831
+ export { BUILT_IN_EVIDENTIAL_ALIASES, BUILT_IN_EVIDENTIAL_EVALUATOR, BUILT_IN_MARKET_INDEX_COMPARATOR, BUILT_IN_METRIC_CHECKER, BUILT_IN_REFERENCE_CHECK_COUNTER, BUILT_IN_TEMPORAL_DEADLINE, DEADLINE_URGENCY, DECAY_TIERS, DEFAULT_NON_INFORMATIVE_WEIGHT, DEFAULT_TEMPORAL_DECAY_HALF_LIFE_MS, DEFAULT_TUPLE_CONTRADICTION_BELIEF_THRESHOLD, DEFAULT_TUPLE_CONTRADICTION_DISBELIEF_THRESHOLD, OPERATOR_TAXONOMY, OPERATOR_TAXONOMY_BY_TAG, OPERATOR_TAXONOMY_ENTRIES, OPERATOR_TAXONOMY_TAGS, PROPAGATION_TRAVERSAL_SPECS, PUBLIC_OPERATOR_EXPORT_NAMES, applyNegativeEvidence, applyNegativeSupport, areTensioned, averagingFusion, bayesianUpdate, betaFromOpinion, buildComparisonRationale, buildEvidentialRationale, clamp012 as clamp01, compareMetricValue, computeBaseDecay, computeDeadlineUrgency, computeEffectiveDecay, conditionalAbduction, conditionalDeduction, confidenceFromOpinion, confidenceFromSL, confidenceLevel, constraintFusion, createInheritedContractRecord, cumulativeFusion, dampedDependencyCascade, dampedDependencyOpinion, decay, deriveContractModulationPlan, deriveContractStatus, deriveVerificationTrigger, detectTupleContradiction, dogmatic, evaluateTupleContradictionTransition, evidenceBalance, getEvaluatorInputRecord, getPropagationTraversalSpecs, getRescoringSchedule, hasProjectedOpinionChanged, informationGain, isPropagationEdgeType, negate, normalizeEvidentialAction, normalizeTupleContradictionPolicy, opinion, opinionFromBaseRate, opinionFromBeta, opinionFromDirichlet, opinionFromDogmatic, opinionFromProjected, opinionFromScalar, parseComparisonOperator, parseEvidentialEvaluatorConfig, parseMarketIndexComparatorConfig, parseMetricCheckerConfig, parseNumericThreshold, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, pickFiniteNumber, project, projectDirichletOpinion, propagateAllEdges, propagateThroughEdge, readOpinionFromRecord, resolveComparisonResult, reviseConfidence, reviseConfidenceOpinion, temporalDecay, toDogmaticOpinion, toStoredOpinionFields, trustDiscount, vacuous };
1832
+ //# sourceMappingURL=index.js.map
1833
+ //# sourceMappingURL=index.js.map