@lucern/confidence 0.3.0-alpha.0 → 0.3.0-alpha.10

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 (54) hide show
  1. package/README.md +5 -1
  2. package/dist/index.d.ts +5 -3
  3. package/dist/index.js +227 -98
  4. package/dist/index.js.map +1 -1
  5. package/dist/v1/codec.d.ts +42 -0
  6. package/dist/v1/codec.js +62 -0
  7. package/dist/v1/codec.js.map +1 -0
  8. package/dist/v1/index.d.ts +5 -3
  9. package/dist/v1/index.js +227 -98
  10. package/dist/v1/index.js.map +1 -1
  11. package/dist/v1/operations/approximation.js +30 -21
  12. package/dist/v1/operations/approximation.js.map +1 -1
  13. package/dist/v1/operations/bridge/index.d.ts +3 -3
  14. package/dist/v1/operations/bridge/index.js +27 -13
  15. package/dist/v1/operations/bridge/index.js.map +1 -1
  16. package/dist/v1/operations/canonical.d.ts +2 -2
  17. package/dist/v1/operations/canonical.js +16 -19
  18. package/dist/v1/operations/canonical.js.map +1 -1
  19. package/dist/v1/operations/contracts/epistemicContract.d.ts +1 -1
  20. package/dist/v1/operations/contracts/epistemicContract.js +13 -11
  21. package/dist/v1/operations/contracts/epistemicContract.js.map +1 -1
  22. package/dist/v1/operations/contradiction/detectTupleContradiction.js.map +1 -1
  23. package/dist/v1/operations/contradiction/index.js.map +1 -1
  24. package/dist/v1/operations/dynamics/cascade.js +19 -6
  25. package/dist/v1/operations/dynamics/cascade.js.map +1 -1
  26. package/dist/v1/operations/dynamics/decay.d.ts +1 -1
  27. package/dist/v1/operations/dynamics/decay.js +5 -4
  28. package/dist/v1/operations/dynamics/decay.js.map +1 -1
  29. package/dist/v1/operations/dynamics/defeat.d.ts +1 -1
  30. package/dist/v1/operations/dynamics/defeat.js +22 -17
  31. package/dist/v1/operations/dynamics/defeat.js.map +1 -1
  32. package/dist/v1/operations/dynamics/propagation.js +66 -33
  33. package/dist/v1/operations/dynamics/propagation.js.map +1 -1
  34. package/dist/v1/operations/dynamics/revision.d.ts +6 -6
  35. package/dist/v1/operations/dynamics/revision.js +31 -19
  36. package/dist/v1/operations/dynamics/revision.js.map +1 -1
  37. package/dist/v1/operations/index.js +9 -5
  38. package/dist/v1/operations/index.js.map +1 -1
  39. package/dist/v1/operations/lucern.d.ts +4 -2
  40. package/dist/v1/operations/lucern.js +192 -87
  41. package/dist/v1/operations/lucern.js.map +1 -1
  42. package/dist/v1/operations/operatorTaxonomy.d.ts +23 -1
  43. package/dist/v1/operations/operatorTaxonomy.js +28 -0
  44. package/dist/v1/operations/operatorTaxonomy.js.map +1 -1
  45. package/dist/v1/operations/scoring.d.ts +30 -12
  46. package/dist/v1/operations/scoring.js +82 -40
  47. package/dist/v1/operations/scoring.js.map +1 -1
  48. package/dist/v1/operations/subjectiveLogic/index.d.ts +20 -19
  49. package/dist/v1/operations/subjectiveLogic/index.js +11 -10
  50. package/dist/v1/operations/subjectiveLogic/index.js.map +1 -1
  51. package/dist/v1/operations/temporalDecay.js +9 -5
  52. package/dist/v1/operations/temporalDecay.js.map +1 -1
  53. package/dist/v1/types.d.ts +5 -1
  54. package/package.json +5 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/v1/operations/subjectiveLogic/index.ts","../../../../src/v1/operations/dynamics/decay.ts"],"names":[],"mappings":"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","file":"decay.js","sourcesContent":["import type { Opinion } from \"../../types\";\n\nexport function opinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number = 0.5\n): Opinion {\n const b = Math.max(0, Math.min(1, belief));\n const d = Math.max(0, Math.min(1, disbelief));\n const u = Math.max(0, Math.min(1, uncertainty));\n const a = Math.max(0, Math.min(1, baseRate));\n const sum = b + d + u;\n\n if (sum === 0) {\n return { b: 0, d: 0, u: 1, a };\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n };\n}\n\nexport function vacuous(baseRate: number = 0.5): Opinion {\n return { b: 0, d: 0, u: 1, a: baseRate };\n}\n\nexport function dogmatic(probability: number, baseRate: number = 0.5): Opinion {\n const p = Math.max(0, Math.min(1, probability));\n return { b: p, d: 1 - p, u: 0, a: baseRate };\n}\n\nexport function project(o: Opinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: Opinion): \"high\" | \"medium\" | \"low\" {\n const projected = project(o);\n if (o.u > 0.5) {\n return \"low\";\n }\n if (projected >= 0.8 && o.u < 0.2) {\n return \"high\";\n }\n if (projected >= 0.6) {\n return \"medium\";\n }\n return \"low\";\n}\n\nexport function cumulativeFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (left.u * right.u) / k,\n (left.a + right.a) / 2\n );\n}\n\nexport function averagingFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (2 * left.u * right.u) / k,\n (left.a + right.a) / 2\n );\n}\n\nexport function trustDiscount(sourceOpinion: Opinion, trust: number): Opinion {\n const weight = Math.max(0, Math.min(1, Math.abs(trust)));\n return opinion(\n weight * sourceOpinion.b,\n weight * sourceOpinion.d,\n 1 - weight * (sourceOpinion.b + sourceOpinion.d),\n sourceOpinion.a\n );\n}\n\nconst EPSILON = 1e-9;\n\nfunction childBaseRateFallback(\n ifTrue: Opinion,\n ifFalse: Opinion,\n fallbackBaseRate: number | undefined\n): number {\n if (fallbackBaseRate !== undefined) {\n return Math.max(0, Math.min(1, fallbackBaseRate));\n }\n\n if (Math.abs(ifTrue.a - ifFalse.a) <= EPSILON) {\n return ifTrue.a;\n }\n\n return (ifTrue.a + ifFalse.a) / 2;\n}\n\nfunction computeConditionalDeductionBaseRate(\n opinionA: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n fallbackBaseRate: number\n): number {\n const denominator =\n 1 - opinionA.a * ifTrue.u - (1 - opinionA.a) * ifFalse.u;\n\n if (ifTrue.u + ifFalse.u < 2 - EPSILON && Math.abs(denominator) > EPSILON) {\n const baseRate =\n (opinionA.a * ifTrue.b + (1 - opinionA.a) * ifFalse.b) / denominator;\n if (baseRate >= -EPSILON && baseRate <= 1 + EPSILON) {\n return Math.max(0, Math.min(1, baseRate));\n }\n }\n\n return fallbackBaseRate;\n}\n\nfunction safeCorrectionTerm(\n numerator: number,\n denominator: number\n): number | undefined {\n if (Math.abs(denominator) <= EPSILON) {\n return undefined;\n }\n\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(0, value);\n}\n\nexport function conditionalDeduction(\n opinionA: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n fallbackBaseRate?: number\n): Opinion {\n const fallbackChildBaseRate = childBaseRateFallback(\n ifTrue,\n ifFalse,\n fallbackBaseRate\n );\n const childBaseRate = computeConditionalDeductionBaseRate(\n opinionA,\n ifTrue,\n ifFalse,\n fallbackChildBaseRate\n );\n const projectedAntecedent = project(opinionA);\n const projectedAntecedentComplement = 1 - projectedAntecedent;\n const intermediateBelief =\n opinionA.b * ifTrue.b +\n opinionA.d * ifFalse.b +\n opinionA.u * (ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a));\n const intermediateDisbelief =\n opinionA.b * ifTrue.d +\n opinionA.d * ifFalse.d +\n opinionA.u * (ifTrue.d * opinionA.a + ifFalse.d * (1 - opinionA.a));\n const intermediateUncertainty =\n opinionA.b * ifTrue.u +\n opinionA.d * ifFalse.u +\n opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedVacuousDeduction =\n ifTrue.b * opinionA.a +\n ifFalse.b * (1 - opinionA.a) +\n childBaseRate *\n (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedConditionalA =\n ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);\n let correction = 0;\n\n if (\n (ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d) ||\n (ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d)\n ) {\n correction = 0;\n } else if (ifTrue.b > ifFalse.b && ifTrue.d <= ifFalse.d) {\n const beliefGap = ifTrue.b - ifFalse.b;\n const disbeliefGap = ifFalse.d - ifTrue.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedent * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,\n projectedAntecedentComplement * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedent * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedentComplement * (1 - childBaseRate)\n ) ?? 0;\n }\n } else {\n const beliefGap = ifFalse.b - ifTrue.b;\n const disbeliefGap = ifTrue.d - ifFalse.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateDisbelief - ifTrue.d) *\n beliefGap,\n projectedAntecedent * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedentComplement * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedent * (1 - childBaseRate)\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n opinionA.a *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedentComplement * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n }\n }\n\n return opinion(\n intermediateBelief - childBaseRate * correction,\n intermediateDisbelief - (1 - childBaseRate) * correction,\n intermediateUncertainty + correction,\n childBaseRate\n );\n}\n\n/**\n * Abductive inference over a conditional.\n * Given an opinion on Y and conditionals P(Y|X), P(Y|~X), infer an opinion on X.\n */\nexport function conditionalAbduction(\n opinionY: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n baseRateX: number\n): Opinion {\n const priorX = Math.max(0, Math.min(1, baseRateX));\n const probabilityY = project(opinionY);\n const probabilityGivenTrue = project(ifTrue);\n const probabilityGivenFalse = project(ifFalse);\n\n const posteriorIfYDenominator =\n probabilityGivenTrue * priorX +\n probabilityGivenFalse * (1 - priorX);\n const posteriorIfY =\n posteriorIfYDenominator === 0\n ? priorX\n : (probabilityGivenTrue * priorX) / posteriorIfYDenominator;\n\n const posteriorIfNotYDenominator =\n (1 - probabilityGivenTrue) * priorX +\n (1 - probabilityGivenFalse) * (1 - priorX);\n const posteriorIfNotY =\n posteriorIfNotYDenominator === 0\n ? priorX\n : ((1 - probabilityGivenTrue) * priorX) / posteriorIfNotYDenominator;\n\n const projectedX =\n probabilityY * posteriorIfY + (1 - probabilityY) * posteriorIfNotY;\n const uncertainty = Math.max(\n opinionY.u * 0.5,\n probabilityY * ifTrue.u + (1 - probabilityY) * ifFalse.u\n );\n\n return opinion(\n projectedX * (1 - uncertainty),\n (1 - projectedX) * (1 - uncertainty),\n uncertainty,\n priorX\n );\n}\n\nexport function negate(o: Opinion): Opinion {\n return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };\n}\n\nexport function constraintFusion(\n left: Opinion,\n right: Opinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: Opinion; o2: Opinion } {\n if (mode === \"redistribute\") {\n const leftProjected = project(left);\n const rightProjected = project(right);\n const total = leftProjected + rightProjected;\n\n if (total <= 1) {\n return { o1: left, o2: right };\n }\n\n const scale = 1 / total;\n return {\n o1: opinion(\n left.b * scale,\n left.d + left.b * (1 - scale),\n left.u,\n left.a\n ),\n o2: opinion(\n right.b * scale,\n right.d + right.b * (1 - scale),\n right.u,\n right.a\n ),\n };\n }\n\n const pressureLeft = right.b * 0.5;\n const pressureRight = left.b * 0.5;\n\n return {\n o1: opinion(\n left.b - pressureLeft * 0.3,\n left.d + pressureLeft * 0.3,\n left.u,\n left.a\n ),\n o2: opinion(\n right.b - pressureRight * 0.3,\n right.d + pressureRight * 0.3,\n right.u,\n right.a\n ),\n };\n}\n\nexport function evidenceBalance(o: Opinion): number {\n const total = o.b + o.d;\n if (total === 0) {\n return 0;\n }\n return (o.b - o.d) / total;\n}\n\nexport function areTensioned(left: Opinion, right: Opinion): boolean {\n return (\n project(left) > 0.5 &&\n project(right) > 0.5 &&\n (left.d > 0.2 || right.d > 0.2)\n );\n}\n\nexport function informationGain(o: Opinion): number {\n if (o.u === 0) {\n return 0;\n }\n if (o.u === 1) {\n return 1;\n }\n return o.u * (1 - Math.abs(o.b - o.d));\n}\n","import type {\n BeliefLifecycleBucket,\n DeadlineUrgency,\n DeadlineUrgencyTier,\n DecayTier,\n EffectiveDecay,\n Opinion,\n RescoringSchedule,\n} from \"../../types\";\nimport { opinion } from \"../subjectiveLogic\";\n\nexport const DECAY_TIERS: Record<string, DecayTier> = {\n FRESH: {\n maxAgeDays: 30,\n weight: 1,\n label: \"fresh\",\n action: \"Full confidence — recently validated\",\n rescoreInDays: 30,\n },\n AGING: {\n maxAgeDays: 90,\n weight: 0.8,\n label: \"aging\",\n action: \"Evidence refresh recommended\",\n rescoreInDays: 14,\n },\n STALE: {\n maxAgeDays: 180,\n weight: 0.5,\n label: \"stale\",\n action: \"Evidence update required before trusting\",\n rescoreInDays: 7,\n },\n EXPIRED: {\n maxAgeDays: Number.POSITIVE_INFINITY,\n weight: 0.2,\n label: \"expired\",\n action: \"Full re-evaluation needed\",\n rescoreInDays: 0,\n },\n};\n\nexport const DEADLINE_URGENCY: Record<string, DeadlineUrgencyTier> = {\n DISTANT: {\n minDaysToDeadline: 365,\n urgencyMultiplier: 1,\n label: \"distant\",\n rescoreIntervalDays: 90,\n action: \"Quarterly confidence check\",\n },\n APPROACHING: {\n minDaysToDeadline: 180,\n urgencyMultiplier: 0.9,\n label: \"approaching\",\n rescoreIntervalDays: 30,\n action: \"Monthly confidence check — conditions may be shifting\",\n },\n NEAR: {\n minDaysToDeadline: 90,\n urgencyMultiplier: 0.75,\n label: \"near\",\n rescoreIntervalDays: 14,\n action: \"Biweekly rescore — deadline within 3 months\",\n },\n IMMINENT: {\n minDaysToDeadline: 30,\n urgencyMultiplier: 0.6,\n label: \"imminent\",\n rescoreIntervalDays: 7,\n action: \"Weekly rescore — deadline within 1 month\",\n },\n CRITICAL: {\n minDaysToDeadline: 7,\n urgencyMultiplier: 0.4,\n label: \"critical\",\n rescoreIntervalDays: 1,\n action: \"Daily rescore — deadline THIS WEEK\",\n },\n OVERDUE: {\n minDaysToDeadline: Number.NEGATIVE_INFINITY,\n urgencyMultiplier: 0.2,\n label: \"overdue\",\n rescoreIntervalDays: 0,\n action: \"OVERDUE — must validate or archive immediately\",\n },\n};\n\nfunction normalizeBeliefConfidence(confidence: unknown): number | null {\n if (typeof confidence !== \"number\" || !Number.isFinite(confidence)) {\n return null;\n }\n if (confidence >= 0 && confidence <= 1) {\n return confidence;\n }\n if (confidence > 1 && confidence <= 100) {\n return confidence / 100;\n }\n return null;\n}\n\nfunction hasResolvedPredictionOutcome(predictionMeta: unknown): boolean {\n if (!predictionMeta || typeof predictionMeta !== \"object\") {\n return false;\n }\n\n const outcome = (predictionMeta as { outcome?: unknown }).outcome;\n return (\n outcome === \"confirmed\" ||\n outcome === \"disconfirmed\" ||\n outcome === \"partial\" ||\n outcome === \"expired\"\n );\n}\n\nfunction resolveLifecycleBucket(args: {\n beliefStatus?: string | null;\n confidence?: unknown;\n predictionMeta?: unknown;\n}): BeliefLifecycleBucket {\n if (\n normalizeBeliefConfidence(args.confidence) === 0 ||\n normalizeBeliefConfidence(args.confidence) === 1 ||\n hasResolvedPredictionOutcome(args.predictionMeta)\n ) {\n return \"fact\";\n }\n\n if (\n args.beliefStatus === \"assumption\" ||\n args.beliefStatus === \"hypothesis\" ||\n args.beliefStatus === \"belief\" ||\n args.beliefStatus === \"fact\"\n ) {\n if (\n normalizeBeliefConfidence(args.confidence) !== null &&\n (args.beliefStatus === \"assumption\" || args.beliefStatus === \"hypothesis\")\n ) {\n return \"belief\";\n }\n return args.beliefStatus;\n }\n\n return \"assumption\";\n}\n\nfunction lifecycleMultiplier(status: BeliefLifecycleBucket | string | null | undefined) {\n if (status === \"assumption\") {\n return 0.65;\n }\n if (status === \"hypothesis\") {\n return 0.8;\n }\n return 1;\n}\n\nexport function computeBaseDecay(lastScoredAt: number): {\n ageDays: number;\n tier: DecayTier;\n weight: number;\n} {\n const ageDays = (Date.now() - lastScoredAt) / (1000 * 60 * 60 * 24);\n let tier = DECAY_TIERS.EXPIRED;\n\n if (ageDays <= DECAY_TIERS.FRESH.maxAgeDays) {\n tier = DECAY_TIERS.FRESH;\n } else if (ageDays <= DECAY_TIERS.AGING.maxAgeDays) {\n tier = DECAY_TIERS.AGING;\n } else if (ageDays <= DECAY_TIERS.STALE.maxAgeDays) {\n tier = DECAY_TIERS.STALE;\n }\n\n return { ageDays, tier, weight: tier.weight };\n}\n\nexport function computeDeadlineUrgency(\n expectedBy: number | null | undefined\n): DeadlineUrgency {\n if (!expectedBy) {\n return null;\n }\n\n const daysToDeadline = (expectedBy - Date.now()) / (1000 * 60 * 60 * 24);\n let urgencyTier = DEADLINE_URGENCY.DISTANT;\n\n if (daysToDeadline < 0) {\n urgencyTier = DEADLINE_URGENCY.OVERDUE;\n } else if (daysToDeadline <= 7) {\n urgencyTier = DEADLINE_URGENCY.CRITICAL;\n } else if (daysToDeadline <= 30) {\n urgencyTier = DEADLINE_URGENCY.IMMINENT;\n } else if (daysToDeadline <= 90) {\n urgencyTier = DEADLINE_URGENCY.NEAR;\n } else if (daysToDeadline <= 180) {\n urgencyTier = DEADLINE_URGENCY.APPROACHING;\n }\n\n return {\n daysToDeadline: Math.round(daysToDeadline),\n urgencyTier,\n urgencyMultiplier: urgencyTier.urgencyMultiplier,\n isOverdue: daysToDeadline < 0,\n };\n}\n\nexport function computeEffectiveDecay(\n lastScoredAt: number,\n expectedBy?: number | null,\n beliefStatus?: BeliefLifecycleBucket | string | null\n): EffectiveDecay {\n const base = computeBaseDecay(lastScoredAt);\n const urgency = computeDeadlineUrgency(expectedBy);\n const effectiveWeight =\n (urgency ? base.weight * urgency.urgencyMultiplier : base.weight) *\n lifecycleMultiplier(beliefStatus);\n\n const urgencyRescoreDays =\n urgency?.urgencyTier.rescoreIntervalDays ?? Number.POSITIVE_INFINITY;\n const rescoreInDays = Math.min(base.tier.rescoreInDays, urgencyRescoreDays);\n const rescoreByDate = lastScoredAt + rescoreInDays * 24 * 60 * 60 * 1000;\n\n let action = base.tier.action;\n if (urgency && urgency.urgencyTier.label !== \"distant\") {\n action = `${urgency.urgencyTier.action}. ${base.tier.action}`;\n }\n\n return {\n ageDays: base.ageDays,\n baseTier: base.tier,\n baseWeight: base.weight,\n urgency,\n effectiveWeight: Math.max(0, Math.min(1, effectiveWeight)),\n rescoreByDate,\n rescoreInDays,\n action,\n };\n}\n\nexport function getRescoringSchedule(opts: {\n lastScoredAt: number;\n temporalNature?: \"factual\" | \"forecast\" | \"unknown\" | null;\n expectedBy?: number | null;\n predictionMeta?: { expectedBy?: number; outcome?: unknown } | null;\n confidence?: number;\n beliefStatus?: string | null;\n}): RescoringSchedule {\n const lifecycleStatus = resolveLifecycleBucket({\n beliefStatus: opts.beliefStatus,\n confidence: opts.confidence,\n predictionMeta: opts.predictionMeta,\n });\n\n const decayState = computeEffectiveDecay(\n opts.lastScoredAt,\n opts.expectedBy,\n lifecycleStatus\n );\n const daysUntilRescore =\n (decayState.rescoreByDate - Date.now()) / (1000 * 60 * 60 * 24);\n const isOverdue = daysUntilRescore < 0;\n\n let priority: RescoringSchedule[\"priority\"];\n let reason: string;\n\n if (isOverdue && lifecycleStatus === \"assumption\") {\n priority = \"critical\";\n reason = `Untested assumption is stale (${Math.round(decayState.ageDays)}d) — validate or supersede`;\n } else if (\n (isOverdue && lifecycleStatus === \"hypothesis\") ||\n (lifecycleStatus === \"hypothesis\" && daysUntilRescore < 7)\n ) {\n priority = \"high\";\n reason = `Hypothesis aging without validation (${Math.round(decayState.ageDays)}d) — run/finish sprint testing`;\n } else if (decayState.urgency?.isOverdue) {\n priority = \"critical\";\n reason = `Prediction deadline passed ${Math.abs(decayState.urgency.daysToDeadline)}d ago — validate or archive`;\n } else if (isOverdue && decayState.baseTier.label === \"expired\") {\n priority = \"critical\";\n reason = `Not scored in ${Math.round(decayState.ageDays)}d — confidence severely degraded`;\n } else if (isOverdue && decayState.baseTier.label === \"stale\") {\n priority = \"high\";\n reason = `Stale (${Math.round(decayState.ageDays)}d since scoring) — evidence update required`;\n } else if (\n decayState.urgency &&\n decayState.urgency.urgencyTier.label === \"critical\"\n ) {\n priority = \"critical\";\n reason = `Deadline in ${decayState.urgency.daysToDeadline}d — needs immediate rescoring`;\n } else if (\n decayState.urgency &&\n decayState.urgency.urgencyTier.label === \"imminent\"\n ) {\n priority = \"high\";\n reason = `Deadline in ${decayState.urgency.daysToDeadline}d — weekly rescoring required`;\n } else if (isOverdue) {\n priority = \"high\";\n reason = `Rescore overdue by ${Math.abs(Math.round(daysUntilRescore))}d`;\n } else if (opts.temporalNature === \"forecast\" && daysUntilRescore < 7) {\n priority = \"medium\";\n reason = `Forecast belief — next rescore due in ${Math.round(daysUntilRescore)}d`;\n } else if (daysUntilRescore < 14) {\n priority = \"medium\";\n reason = `Rescore due in ${Math.round(daysUntilRescore)}d`;\n } else {\n priority = \"low\";\n reason = `On schedule — next rescore in ${Math.round(daysUntilRescore)}d`;\n }\n\n if (\n (opts.confidence ?? 0) >= 0.8 &&\n decayState.baseTier.label !== \"fresh\" &&\n priority === \"medium\"\n ) {\n priority = \"high\";\n reason = `High-confidence belief (${((opts.confidence ?? 0) * 100).toFixed(0)}%) aging without rescore — ${reason}`;\n }\n\n return {\n nextRescoreBy: decayState.rescoreByDate,\n daysUntilRescore: Math.round(daysUntilRescore),\n isOverdue,\n priority,\n reason,\n decay: decayState,\n };\n}\n\nexport function decay(\n current: Opinion,\n daysSinceLastUpdate: number,\n halfLifeDays: number = 90\n): Opinion {\n if (daysSinceLastUpdate <= 0) {\n return current;\n }\n\n const decayFactor = Math.pow(0.5, daysSinceLastUpdate / halfLifeDays);\n const certainty = current.b + current.d;\n const lostCertainty = certainty - certainty * decayFactor;\n\n return opinion(\n current.b * decayFactor,\n current.d * decayFactor,\n current.u + lostCertainty,\n current.a\n );\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/v1/operations/subjectiveLogic/index.ts","../../../../src/v1/operations/dynamics/decay.ts"],"names":[],"mappings":"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","file":"decay.js","sourcesContent":["import type { SLOpinion } from \"../../types\";\n\nexport function mkOpinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n const b = Number.isFinite(belief) ? Math.max(0, belief) : 0;\n const d = Number.isFinite(disbelief) ? Math.max(0, disbelief) : 0;\n const u = Number.isFinite(uncertainty) ? Math.max(0, uncertainty) : 0;\n const a = Math.max(0, Math.min(1, baseRate));\n const sum = b + d + u;\n\n if (sum === 0) {\n return { b: 0, d: 0, u: 1, a } as SLOpinion;\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n } as SLOpinion;\n}\n\nexport const opinion = mkOpinion;\n\nexport function vacuous(baseRate: number): SLOpinion {\n return mkOpinion(0, 0, 1, baseRate);\n}\n\nexport function dogmatic(probability: number, baseRate: number): SLOpinion {\n const p = Math.max(0, Math.min(1, probability));\n return mkOpinion(p, 1 - p, 0, baseRate);\n}\n\nexport function project(o: SLOpinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: SLOpinion): \"high\" | \"medium\" | \"low\" {\n const projected = project(o);\n if (o.u > 0.5) {\n return \"low\";\n }\n if (projected >= 0.8 && o.u < 0.2) {\n return \"high\";\n }\n if (projected >= 0.6) {\n return \"medium\";\n }\n return \"low\";\n}\n\nexport function cumulativeFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (left.u * right.u) / k,\n (left.a + right.a) / 2\n );\n}\n\nexport function averagingFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (2 * left.u * right.u) / k,\n (left.a + right.a) / 2\n );\n}\n\nexport function trustDiscount(sourceOpinion: SLOpinion, trust: number): SLOpinion {\n const weight = Math.max(0, Math.min(1, Math.abs(trust)));\n return opinion(\n weight * sourceOpinion.b,\n weight * sourceOpinion.d,\n 1 - weight * (sourceOpinion.b + sourceOpinion.d),\n sourceOpinion.a\n );\n}\n\nconst EPSILON = 1e-9;\n\nfunction childBaseRateFallback(\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number | undefined\n): number {\n if (fallbackBaseRate !== undefined) {\n return Math.max(0, Math.min(1, fallbackBaseRate));\n }\n\n if (Math.abs(ifTrue.a - ifFalse.a) <= EPSILON) {\n return ifTrue.a;\n }\n\n return (ifTrue.a + ifFalse.a) / 2;\n}\n\nfunction computeConditionalDeductionBaseRate(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number\n): number {\n const denominator =\n 1 - opinionA.a * ifTrue.u - (1 - opinionA.a) * ifFalse.u;\n\n if (ifTrue.u + ifFalse.u < 2 - EPSILON && Math.abs(denominator) > EPSILON) {\n const baseRate =\n (opinionA.a * ifTrue.b + (1 - opinionA.a) * ifFalse.b) / denominator;\n if (baseRate >= -EPSILON && baseRate <= 1 + EPSILON) {\n return Math.max(0, Math.min(1, baseRate));\n }\n }\n\n return fallbackBaseRate;\n}\n\nfunction safeCorrectionTerm(\n numerator: number,\n denominator: number\n): number | undefined {\n if (Math.abs(denominator) <= EPSILON) {\n return undefined;\n }\n\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(0, value);\n}\n\nexport function conditionalDeduction(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate?: number\n): SLOpinion {\n const fallbackChildBaseRate = childBaseRateFallback(\n ifTrue,\n ifFalse,\n fallbackBaseRate\n );\n const childBaseRate = computeConditionalDeductionBaseRate(\n opinionA,\n ifTrue,\n ifFalse,\n fallbackChildBaseRate\n );\n const projectedAntecedent = project(opinionA);\n const projectedAntecedentComplement = 1 - projectedAntecedent;\n const intermediateBelief =\n opinionA.b * ifTrue.b +\n opinionA.d * ifFalse.b +\n opinionA.u * (ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a));\n const intermediateDisbelief =\n opinionA.b * ifTrue.d +\n opinionA.d * ifFalse.d +\n opinionA.u * (ifTrue.d * opinionA.a + ifFalse.d * (1 - opinionA.a));\n const intermediateUncertainty =\n opinionA.b * ifTrue.u +\n opinionA.d * ifFalse.u +\n opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedVacuousDeduction =\n ifTrue.b * opinionA.a +\n ifFalse.b * (1 - opinionA.a) +\n childBaseRate *\n (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedConditionalA =\n ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);\n let correction = 0;\n\n if (\n (ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d) ||\n (ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d)\n ) {\n correction = 0;\n } else if (ifTrue.b > ifFalse.b && ifTrue.d <= ifFalse.d) {\n const beliefGap = ifTrue.b - ifFalse.b;\n const disbeliefGap = ifFalse.d - ifTrue.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedent * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,\n projectedAntecedentComplement * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedent * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedentComplement * (1 - childBaseRate)\n ) ?? 0;\n }\n } else {\n const beliefGap = ifFalse.b - ifTrue.b;\n const disbeliefGap = ifTrue.d - ifFalse.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateDisbelief - ifTrue.d) *\n beliefGap,\n projectedAntecedent * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedentComplement * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedent * (1 - childBaseRate)\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n opinionA.a *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedentComplement * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n }\n }\n\n return opinion(\n intermediateBelief - childBaseRate * correction,\n intermediateDisbelief - (1 - childBaseRate) * correction,\n intermediateUncertainty + correction,\n childBaseRate\n );\n}\n\n/**\n * Abductive inference over a conditional.\n * Given an opinion on Y and conditionals P(Y|X), P(Y|~X), infer an opinion on X.\n */\nexport function conditionalAbduction(\n opinionY: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n baseRateX: number\n): SLOpinion {\n const priorX = Math.max(0, Math.min(1, baseRateX));\n const probabilityY = project(opinionY);\n const probabilityGivenTrue = project(ifTrue);\n const probabilityGivenFalse = project(ifFalse);\n\n const posteriorIfYDenominator =\n probabilityGivenTrue * priorX +\n probabilityGivenFalse * (1 - priorX);\n const posteriorIfY =\n posteriorIfYDenominator === 0\n ? priorX\n : (probabilityGivenTrue * priorX) / posteriorIfYDenominator;\n\n const posteriorIfNotYDenominator =\n (1 - probabilityGivenTrue) * priorX +\n (1 - probabilityGivenFalse) * (1 - priorX);\n const posteriorIfNotY =\n posteriorIfNotYDenominator === 0\n ? priorX\n : ((1 - probabilityGivenTrue) * priorX) / posteriorIfNotYDenominator;\n\n const projectedX =\n probabilityY * posteriorIfY + (1 - probabilityY) * posteriorIfNotY;\n const uncertainty = Math.max(\n opinionY.u * 0.5,\n probabilityY * ifTrue.u + (1 - probabilityY) * ifFalse.u\n );\n\n return opinion(\n projectedX * (1 - uncertainty),\n (1 - projectedX) * (1 - uncertainty),\n uncertainty,\n priorX\n );\n}\n\nexport function negate(o: SLOpinion): SLOpinion {\n return mkOpinion(o.d, o.b, o.u, 1 - o.a);\n}\n\nexport function constraintFusion(\n left: SLOpinion,\n right: SLOpinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: SLOpinion; o2: SLOpinion } {\n if (mode === \"redistribute\") {\n const leftProjected = project(left);\n const rightProjected = project(right);\n const total = leftProjected + rightProjected;\n\n if (total <= 1) {\n return { o1: left, o2: right };\n }\n\n const scale = 1 / total;\n return {\n o1: opinion(\n left.b * scale,\n left.d + left.b * (1 - scale),\n left.u,\n left.a\n ),\n o2: opinion(\n right.b * scale,\n right.d + right.b * (1 - scale),\n right.u,\n right.a\n ),\n };\n }\n\n const pressureLeft = right.b * 0.5;\n const pressureRight = left.b * 0.5;\n\n return {\n o1: opinion(\n left.b - pressureLeft * 0.3,\n left.d + pressureLeft * 0.3,\n left.u,\n left.a\n ),\n o2: opinion(\n right.b - pressureRight * 0.3,\n right.d + pressureRight * 0.3,\n right.u,\n right.a\n ),\n };\n}\n\nexport function evidenceBalance(o: SLOpinion): number {\n const total = o.b + o.d;\n if (total === 0) {\n return 0;\n }\n return (o.b - o.d) / total;\n}\n\nexport function areTensioned(left: SLOpinion, right: SLOpinion): boolean {\n return (\n project(left) > 0.5 &&\n project(right) > 0.5 &&\n (left.d > 0.2 || right.d > 0.2)\n );\n}\n\nexport function informationGain(o: SLOpinion): number {\n if (o.u === 0) {\n return 0;\n }\n if (o.u === 1) {\n return 1;\n }\n return o.u * (1 - Math.abs(o.b - o.d));\n}\n","import type {\n BeliefLifecycleBucket,\n DeadlineUrgency,\n DeadlineUrgencyTier,\n DecayTier,\n EffectiveDecay,\n Opinion,\n RescoringSchedule,\n} from \"../../types\";\nimport { opinion } from \"../subjectiveLogic\";\n\nexport const DECAY_TIERS: Record<string, DecayTier> = {\n FRESH: {\n maxAgeDays: 30,\n weight: 1,\n label: \"fresh\",\n action: \"Full confidence — recently validated\",\n rescoreInDays: 30,\n },\n AGING: {\n maxAgeDays: 90,\n weight: 0.8,\n label: \"aging\",\n action: \"Evidence refresh recommended\",\n rescoreInDays: 14,\n },\n STALE: {\n maxAgeDays: 180,\n weight: 0.5,\n label: \"stale\",\n action: \"Evidence update required before trusting\",\n rescoreInDays: 7,\n },\n EXPIRED: {\n maxAgeDays: Number.POSITIVE_INFINITY,\n weight: 0.2,\n label: \"expired\",\n action: \"Full re-evaluation needed\",\n rescoreInDays: 0,\n },\n};\n\nexport const DEADLINE_URGENCY: Record<string, DeadlineUrgencyTier> = {\n DISTANT: {\n minDaysToDeadline: 365,\n urgencyMultiplier: 1,\n label: \"distant\",\n rescoreIntervalDays: 90,\n action: \"Quarterly confidence check\",\n },\n APPROACHING: {\n minDaysToDeadline: 180,\n urgencyMultiplier: 0.9,\n label: \"approaching\",\n rescoreIntervalDays: 30,\n action: \"Monthly confidence check — conditions may be shifting\",\n },\n NEAR: {\n minDaysToDeadline: 90,\n urgencyMultiplier: 0.75,\n label: \"near\",\n rescoreIntervalDays: 14,\n action: \"Biweekly rescore — deadline within 3 months\",\n },\n IMMINENT: {\n minDaysToDeadline: 30,\n urgencyMultiplier: 0.6,\n label: \"imminent\",\n rescoreIntervalDays: 7,\n action: \"Weekly rescore — deadline within 1 month\",\n },\n CRITICAL: {\n minDaysToDeadline: 7,\n urgencyMultiplier: 0.4,\n label: \"critical\",\n rescoreIntervalDays: 1,\n action: \"Daily rescore — deadline THIS WEEK\",\n },\n OVERDUE: {\n minDaysToDeadline: Number.NEGATIVE_INFINITY,\n urgencyMultiplier: 0.2,\n label: \"overdue\",\n rescoreIntervalDays: 0,\n action: \"OVERDUE — must validate or archive immediately\",\n },\n};\n\nfunction normalizeBeliefConfidence(confidence: unknown): number | null {\n if (typeof confidence !== \"number\" || !Number.isFinite(confidence)) {\n return null;\n }\n if (confidence >= 0 && confidence <= 1) {\n return confidence;\n }\n if (confidence > 1 && confidence <= 100) {\n return confidence / 100;\n }\n return null;\n}\n\nfunction hasResolvedPredictionOutcome(predictionMeta: unknown): boolean {\n if (!predictionMeta || typeof predictionMeta !== \"object\") {\n return false;\n }\n\n const outcome = (predictionMeta as { outcome?: unknown }).outcome;\n return (\n outcome === \"confirmed\" ||\n outcome === \"disconfirmed\" ||\n outcome === \"partial\" ||\n outcome === \"expired\"\n );\n}\n\nfunction resolveLifecycleBucket(args: {\n beliefStatus?: string | null;\n confidence?: unknown;\n predictionMeta?: unknown;\n}): BeliefLifecycleBucket {\n if (\n normalizeBeliefConfidence(args.confidence) === 0 ||\n normalizeBeliefConfidence(args.confidence) === 1 ||\n hasResolvedPredictionOutcome(args.predictionMeta)\n ) {\n return \"fact\";\n }\n\n if (\n args.beliefStatus === \"assumption\" ||\n args.beliefStatus === \"hypothesis\" ||\n args.beliefStatus === \"belief\" ||\n args.beliefStatus === \"fact\"\n ) {\n if (\n normalizeBeliefConfidence(args.confidence) !== null &&\n (args.beliefStatus === \"assumption\" || args.beliefStatus === \"hypothesis\")\n ) {\n return \"belief\";\n }\n return args.beliefStatus;\n }\n\n return \"assumption\";\n}\n\nfunction lifecycleMultiplier(status: BeliefLifecycleBucket | string | null | undefined) {\n if (status === \"assumption\") {\n return 0.65;\n }\n if (status === \"hypothesis\") {\n return 0.8;\n }\n return 1;\n}\n\nexport function computeBaseDecay(lastScoredAt: number): {\n ageDays: number;\n tier: DecayTier;\n weight: number;\n} {\n const ageDays = (Date.now() - lastScoredAt) / (1000 * 60 * 60 * 24);\n let tier = DECAY_TIERS.EXPIRED;\n\n if (ageDays <= DECAY_TIERS.FRESH.maxAgeDays) {\n tier = DECAY_TIERS.FRESH;\n } else if (ageDays <= DECAY_TIERS.AGING.maxAgeDays) {\n tier = DECAY_TIERS.AGING;\n } else if (ageDays <= DECAY_TIERS.STALE.maxAgeDays) {\n tier = DECAY_TIERS.STALE;\n }\n\n return { ageDays, tier, weight: tier.weight };\n}\n\nexport function computeDeadlineUrgency(\n expectedBy: number | null | undefined\n): DeadlineUrgency {\n if (!expectedBy) {\n return null;\n }\n\n const daysToDeadline = (expectedBy - Date.now()) / (1000 * 60 * 60 * 24);\n let urgencyTier = DEADLINE_URGENCY.DISTANT;\n\n if (daysToDeadline < 0) {\n urgencyTier = DEADLINE_URGENCY.OVERDUE;\n } else if (daysToDeadline <= 7) {\n urgencyTier = DEADLINE_URGENCY.CRITICAL;\n } else if (daysToDeadline <= 30) {\n urgencyTier = DEADLINE_URGENCY.IMMINENT;\n } else if (daysToDeadline <= 90) {\n urgencyTier = DEADLINE_URGENCY.NEAR;\n } else if (daysToDeadline <= 180) {\n urgencyTier = DEADLINE_URGENCY.APPROACHING;\n }\n\n return {\n daysToDeadline: Math.round(daysToDeadline),\n urgencyTier,\n urgencyMultiplier: urgencyTier.urgencyMultiplier,\n isOverdue: daysToDeadline < 0,\n };\n}\n\nexport function computeEffectiveDecay(\n lastScoredAt: number,\n expectedBy?: number | null,\n beliefStatus?: BeliefLifecycleBucket | string | null\n): EffectiveDecay {\n const base = computeBaseDecay(lastScoredAt);\n const urgency = computeDeadlineUrgency(expectedBy);\n const effectiveWeight =\n (urgency ? base.weight * urgency.urgencyMultiplier : base.weight) *\n lifecycleMultiplier(beliefStatus);\n\n const urgencyRescoreDays =\n urgency?.urgencyTier.rescoreIntervalDays ?? Number.POSITIVE_INFINITY;\n const rescoreInDays = Math.min(base.tier.rescoreInDays, urgencyRescoreDays);\n const rescoreByDate = lastScoredAt + rescoreInDays * 24 * 60 * 60 * 1000;\n\n let action = base.tier.action;\n if (urgency && urgency.urgencyTier.label !== \"distant\") {\n action = `${urgency.urgencyTier.action}. ${base.tier.action}`;\n }\n\n return {\n ageDays: base.ageDays,\n baseTier: base.tier,\n baseWeight: base.weight,\n urgency,\n effectiveWeight: Math.max(0, Math.min(1, effectiveWeight)),\n rescoreByDate,\n rescoreInDays,\n action,\n };\n}\n\nexport function getRescoringSchedule(opts: {\n lastScoredAt: number;\n temporalNature?: \"factual\" | \"forecast\" | \"unknown\" | null;\n expectedBy?: number | null;\n predictionMeta?: { expectedBy?: number; outcome?: unknown } | null;\n confidence?: number;\n beliefStatus?: string | null;\n}): RescoringSchedule {\n const lifecycleStatus = resolveLifecycleBucket({\n beliefStatus: opts.beliefStatus,\n confidence: opts.confidence,\n predictionMeta: opts.predictionMeta,\n });\n\n const decayState = computeEffectiveDecay(\n opts.lastScoredAt,\n opts.expectedBy,\n lifecycleStatus\n );\n const daysUntilRescore =\n (decayState.rescoreByDate - Date.now()) / (1000 * 60 * 60 * 24);\n const isOverdue = daysUntilRescore < 0;\n\n let priority: RescoringSchedule[\"priority\"];\n let reason: string;\n\n if (isOverdue && lifecycleStatus === \"assumption\") {\n priority = \"critical\";\n reason = `Untested assumption is stale (${Math.round(decayState.ageDays)}d) — validate or supersede`;\n } else if (\n (isOverdue && lifecycleStatus === \"hypothesis\") ||\n (lifecycleStatus === \"hypothesis\" && daysUntilRescore < 7)\n ) {\n priority = \"high\";\n reason = `Hypothesis aging without validation (${Math.round(decayState.ageDays)}d) — run/finish sprint testing`;\n } else if (decayState.urgency?.isOverdue) {\n priority = \"critical\";\n reason = `Prediction deadline passed ${Math.abs(decayState.urgency.daysToDeadline)}d ago — validate or archive`;\n } else if (isOverdue && decayState.baseTier.label === \"expired\") {\n priority = \"critical\";\n reason = `Not scored in ${Math.round(decayState.ageDays)}d — confidence severely degraded`;\n } else if (isOverdue && decayState.baseTier.label === \"stale\") {\n priority = \"high\";\n reason = `Stale (${Math.round(decayState.ageDays)}d since scoring) — evidence update required`;\n } else if (\n decayState.urgency &&\n decayState.urgency.urgencyTier.label === \"critical\"\n ) {\n priority = \"critical\";\n reason = `Deadline in ${decayState.urgency.daysToDeadline}d — needs immediate rescoring`;\n } else if (\n decayState.urgency &&\n decayState.urgency.urgencyTier.label === \"imminent\"\n ) {\n priority = \"high\";\n reason = `Deadline in ${decayState.urgency.daysToDeadline}d — weekly rescoring required`;\n } else if (isOverdue) {\n priority = \"high\";\n reason = `Rescore overdue by ${Math.abs(Math.round(daysUntilRescore))}d`;\n } else if (opts.temporalNature === \"forecast\" && daysUntilRescore < 7) {\n priority = \"medium\";\n reason = `Forecast belief — next rescore due in ${Math.round(daysUntilRescore)}d`;\n } else if (daysUntilRescore < 14) {\n priority = \"medium\";\n reason = `Rescore due in ${Math.round(daysUntilRescore)}d`;\n } else {\n priority = \"low\";\n reason = `On schedule — next rescore in ${Math.round(daysUntilRescore)}d`;\n }\n\n if (\n (opts.confidence ?? 0) >= 0.8 &&\n decayState.baseTier.label !== \"fresh\" &&\n priority === \"medium\"\n ) {\n priority = \"high\";\n reason = `High-confidence belief (${((opts.confidence ?? 0) * 100).toFixed(0)}%) aging without rescore — ${reason}`;\n }\n\n return {\n nextRescoreBy: decayState.rescoreByDate,\n daysUntilRescore: Math.round(daysUntilRescore),\n isOverdue,\n priority,\n reason,\n decay: decayState,\n };\n}\n\nexport function decay(\n current: Opinion,\n daysSinceLastUpdate: number,\n halfLifeDays: number = 90\n): Opinion {\n if (daysSinceLastUpdate <= 0) {\n return current;\n }\n\n const decayFactor = Math.pow(0.5, daysSinceLastUpdate / halfLifeDays);\n const certainty = current.b + current.d;\n const lostCertainty = certainty - certainty * decayFactor;\n\n return opinion(\n current.b * decayFactor,\n current.d * decayFactor,\n current.u + lostCertainty,\n current.a\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Opinion, EdgeMetadata, PropagationResult } from '../../types.js';
1
+ import { Opinion, PropagationResult, EdgeMetadata } from '../../types.js';
2
2
 
3
3
  declare function applyNegativeSupport(source: Opinion, target: Opinion, weight: number, metadata?: EdgeMetadata): PropagationResult;
4
4
  declare function applyNegativeEvidence(source: Opinion, target: Opinion, weight: number): PropagationResult;
@@ -1,8 +1,8 @@
1
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));
2
+ function mkOpinion(belief, disbelief, uncertainty, baseRate) {
3
+ const b = Number.isFinite(belief) ? Math.max(0, belief) : 0;
4
+ const d = Number.isFinite(disbelief) ? Math.max(0, disbelief) : 0;
5
+ const u = Number.isFinite(uncertainty) ? Math.max(0, uncertainty) : 0;
6
6
  const a = Math.max(0, Math.min(1, baseRate));
7
7
  const sum = b + d + u;
8
8
  if (sum === 0) {
@@ -15,8 +15,9 @@ function opinion(belief, disbelief, uncertainty, baseRate = 0.5) {
15
15
  a
16
16
  };
17
17
  }
18
- function vacuous(baseRate = 0.5) {
19
- return { b: 0, d: 0, u: 1, a: baseRate };
18
+ var opinion = mkOpinion;
19
+ function vacuous(baseRate) {
20
+ return mkOpinion(0, 0, 1, baseRate);
20
21
  }
21
22
  function project(o) {
22
23
  return o.b + o.a * o.u;
@@ -51,7 +52,7 @@ function trustDiscount(sourceOpinion, trust) {
51
52
  );
52
53
  }
53
54
  function negate(o) {
54
- return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };
55
+ return mkOpinion(o.d, o.b, o.u, 1 - o.a);
55
56
  }
56
57
  function constraintFusion(left, right, mode = "pressure") {
57
58
  if (mode === "redistribute") {
@@ -97,33 +98,37 @@ function constraintFusion(left, right, mode = "pressure") {
97
98
 
98
99
  // src/v1/operations/dynamics/defeat.ts
99
100
  function applyNegativeSupport(source, target, weight, metadata = {}) {
101
+ const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
102
+ const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
100
103
  if (metadata.constraint === "xor") {
101
104
  const result = constraintFusion(
102
- source,
103
- target,
105
+ sourceOpinion,
106
+ targetOpinion,
104
107
  metadata.normalization ?? "pressure"
105
108
  );
106
109
  return {
107
110
  opinion: result.o2,
108
111
  operator: "constraint_fusion",
109
- rationale: `XOR constraint: source belief at ${project(source).toFixed(
110
- 2
111
- )} pressures target`
112
+ rationale: `XOR constraint: source belief at ${project(
113
+ sourceOpinion
114
+ ).toFixed(2)} pressures target`
112
115
  };
113
116
  }
114
- const discounted = trustDiscount(negate(source), Math.abs(weight));
117
+ const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));
115
118
  return {
116
- opinion: cumulativeFusion(target, discounted),
119
+ opinion: cumulativeFusion(targetOpinion, discounted),
117
120
  operator: "cumulative_fusion",
118
121
  rationale: `Contradicting evidence (weight=${weight.toFixed(
119
122
  2
120
- )}) from source at ${project(source).toFixed(2)}`
123
+ )}) from source at ${project(sourceOpinion).toFixed(2)}`
121
124
  };
122
125
  }
123
126
  function applyNegativeEvidence(source, target, weight) {
124
- const discounted = trustDiscount(negate(source), Math.abs(weight));
127
+ const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
128
+ const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
129
+ const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));
125
130
  return {
126
- opinion: cumulativeFusion(target, discounted),
131
+ opinion: cumulativeFusion(targetOpinion, discounted),
127
132
  operator: "cumulative_fusion",
128
133
  rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`
129
134
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/v1/operations/subjectiveLogic/index.ts","../../../../src/v1/operations/dynamics/defeat.ts"],"names":[],"mappings":"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","file":"defeat.js","sourcesContent":["import type { Opinion } from \"../../types\";\n\nexport function opinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number = 0.5\n): Opinion {\n const b = Math.max(0, Math.min(1, belief));\n const d = Math.max(0, Math.min(1, disbelief));\n const u = Math.max(0, Math.min(1, uncertainty));\n const a = Math.max(0, Math.min(1, baseRate));\n const sum = b + d + u;\n\n if (sum === 0) {\n return { b: 0, d: 0, u: 1, a };\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n };\n}\n\nexport function vacuous(baseRate: number = 0.5): Opinion {\n return { b: 0, d: 0, u: 1, a: baseRate };\n}\n\nexport function dogmatic(probability: number, baseRate: number = 0.5): Opinion {\n const p = Math.max(0, Math.min(1, probability));\n return { b: p, d: 1 - p, u: 0, a: baseRate };\n}\n\nexport function project(o: Opinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: Opinion): \"high\" | \"medium\" | \"low\" {\n const projected = project(o);\n if (o.u > 0.5) {\n return \"low\";\n }\n if (projected >= 0.8 && o.u < 0.2) {\n return \"high\";\n }\n if (projected >= 0.6) {\n return \"medium\";\n }\n return \"low\";\n}\n\nexport function cumulativeFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (left.u * right.u) / k,\n (left.a + right.a) / 2\n );\n}\n\nexport function averagingFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (2 * left.u * right.u) / k,\n (left.a + right.a) / 2\n );\n}\n\nexport function trustDiscount(sourceOpinion: Opinion, trust: number): Opinion {\n const weight = Math.max(0, Math.min(1, Math.abs(trust)));\n return opinion(\n weight * sourceOpinion.b,\n weight * sourceOpinion.d,\n 1 - weight * (sourceOpinion.b + sourceOpinion.d),\n sourceOpinion.a\n );\n}\n\nconst EPSILON = 1e-9;\n\nfunction childBaseRateFallback(\n ifTrue: Opinion,\n ifFalse: Opinion,\n fallbackBaseRate: number | undefined\n): number {\n if (fallbackBaseRate !== undefined) {\n return Math.max(0, Math.min(1, fallbackBaseRate));\n }\n\n if (Math.abs(ifTrue.a - ifFalse.a) <= EPSILON) {\n return ifTrue.a;\n }\n\n return (ifTrue.a + ifFalse.a) / 2;\n}\n\nfunction computeConditionalDeductionBaseRate(\n opinionA: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n fallbackBaseRate: number\n): number {\n const denominator =\n 1 - opinionA.a * ifTrue.u - (1 - opinionA.a) * ifFalse.u;\n\n if (ifTrue.u + ifFalse.u < 2 - EPSILON && Math.abs(denominator) > EPSILON) {\n const baseRate =\n (opinionA.a * ifTrue.b + (1 - opinionA.a) * ifFalse.b) / denominator;\n if (baseRate >= -EPSILON && baseRate <= 1 + EPSILON) {\n return Math.max(0, Math.min(1, baseRate));\n }\n }\n\n return fallbackBaseRate;\n}\n\nfunction safeCorrectionTerm(\n numerator: number,\n denominator: number\n): number | undefined {\n if (Math.abs(denominator) <= EPSILON) {\n return undefined;\n }\n\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(0, value);\n}\n\nexport function conditionalDeduction(\n opinionA: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n fallbackBaseRate?: number\n): Opinion {\n const fallbackChildBaseRate = childBaseRateFallback(\n ifTrue,\n ifFalse,\n fallbackBaseRate\n );\n const childBaseRate = computeConditionalDeductionBaseRate(\n opinionA,\n ifTrue,\n ifFalse,\n fallbackChildBaseRate\n );\n const projectedAntecedent = project(opinionA);\n const projectedAntecedentComplement = 1 - projectedAntecedent;\n const intermediateBelief =\n opinionA.b * ifTrue.b +\n opinionA.d * ifFalse.b +\n opinionA.u * (ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a));\n const intermediateDisbelief =\n opinionA.b * ifTrue.d +\n opinionA.d * ifFalse.d +\n opinionA.u * (ifTrue.d * opinionA.a + ifFalse.d * (1 - opinionA.a));\n const intermediateUncertainty =\n opinionA.b * ifTrue.u +\n opinionA.d * ifFalse.u +\n opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedVacuousDeduction =\n ifTrue.b * opinionA.a +\n ifFalse.b * (1 - opinionA.a) +\n childBaseRate *\n (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedConditionalA =\n ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);\n let correction = 0;\n\n if (\n (ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d) ||\n (ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d)\n ) {\n correction = 0;\n } else if (ifTrue.b > ifFalse.b && ifTrue.d <= ifFalse.d) {\n const beliefGap = ifTrue.b - ifFalse.b;\n const disbeliefGap = ifFalse.d - ifTrue.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedent * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,\n projectedAntecedentComplement * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedent * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedentComplement * (1 - childBaseRate)\n ) ?? 0;\n }\n } else {\n const beliefGap = ifFalse.b - ifTrue.b;\n const disbeliefGap = ifTrue.d - ifFalse.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateDisbelief - ifTrue.d) *\n beliefGap,\n projectedAntecedent * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedentComplement * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedent * (1 - childBaseRate)\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n opinionA.a *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedentComplement * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n }\n }\n\n return opinion(\n intermediateBelief - childBaseRate * correction,\n intermediateDisbelief - (1 - childBaseRate) * correction,\n intermediateUncertainty + correction,\n childBaseRate\n );\n}\n\n/**\n * Abductive inference over a conditional.\n * Given an opinion on Y and conditionals P(Y|X), P(Y|~X), infer an opinion on X.\n */\nexport function conditionalAbduction(\n opinionY: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n baseRateX: number\n): Opinion {\n const priorX = Math.max(0, Math.min(1, baseRateX));\n const probabilityY = project(opinionY);\n const probabilityGivenTrue = project(ifTrue);\n const probabilityGivenFalse = project(ifFalse);\n\n const posteriorIfYDenominator =\n probabilityGivenTrue * priorX +\n probabilityGivenFalse * (1 - priorX);\n const posteriorIfY =\n posteriorIfYDenominator === 0\n ? priorX\n : (probabilityGivenTrue * priorX) / posteriorIfYDenominator;\n\n const posteriorIfNotYDenominator =\n (1 - probabilityGivenTrue) * priorX +\n (1 - probabilityGivenFalse) * (1 - priorX);\n const posteriorIfNotY =\n posteriorIfNotYDenominator === 0\n ? priorX\n : ((1 - probabilityGivenTrue) * priorX) / posteriorIfNotYDenominator;\n\n const projectedX =\n probabilityY * posteriorIfY + (1 - probabilityY) * posteriorIfNotY;\n const uncertainty = Math.max(\n opinionY.u * 0.5,\n probabilityY * ifTrue.u + (1 - probabilityY) * ifFalse.u\n );\n\n return opinion(\n projectedX * (1 - uncertainty),\n (1 - projectedX) * (1 - uncertainty),\n uncertainty,\n priorX\n );\n}\n\nexport function negate(o: Opinion): Opinion {\n return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };\n}\n\nexport function constraintFusion(\n left: Opinion,\n right: Opinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: Opinion; o2: Opinion } {\n if (mode === \"redistribute\") {\n const leftProjected = project(left);\n const rightProjected = project(right);\n const total = leftProjected + rightProjected;\n\n if (total <= 1) {\n return { o1: left, o2: right };\n }\n\n const scale = 1 / total;\n return {\n o1: opinion(\n left.b * scale,\n left.d + left.b * (1 - scale),\n left.u,\n left.a\n ),\n o2: opinion(\n right.b * scale,\n right.d + right.b * (1 - scale),\n right.u,\n right.a\n ),\n };\n }\n\n const pressureLeft = right.b * 0.5;\n const pressureRight = left.b * 0.5;\n\n return {\n o1: opinion(\n left.b - pressureLeft * 0.3,\n left.d + pressureLeft * 0.3,\n left.u,\n left.a\n ),\n o2: opinion(\n right.b - pressureRight * 0.3,\n right.d + pressureRight * 0.3,\n right.u,\n right.a\n ),\n };\n}\n\nexport function evidenceBalance(o: Opinion): number {\n const total = o.b + o.d;\n if (total === 0) {\n return 0;\n }\n return (o.b - o.d) / total;\n}\n\nexport function areTensioned(left: Opinion, right: Opinion): boolean {\n return (\n project(left) > 0.5 &&\n project(right) > 0.5 &&\n (left.d > 0.2 || right.d > 0.2)\n );\n}\n\nexport function informationGain(o: Opinion): number {\n if (o.u === 0) {\n return 0;\n }\n if (o.u === 1) {\n return 1;\n }\n return o.u * (1 - Math.abs(o.b - o.d));\n}\n","import type { EdgeMetadata, Opinion, PropagationResult } from \"../../types\";\nimport {\n constraintFusion,\n cumulativeFusion,\n negate,\n project,\n trustDiscount,\n} from \"../subjectiveLogic\";\n\nexport function applyNegativeSupport(\n source: Opinion,\n target: Opinion,\n weight: number,\n metadata: EdgeMetadata = {}\n): PropagationResult {\n if (metadata.constraint === \"xor\") {\n const result = constraintFusion(\n source,\n target,\n metadata.normalization ?? \"pressure\"\n );\n return {\n opinion: result.o2,\n operator: \"constraint_fusion\",\n rationale: `XOR constraint: source belief at ${project(source).toFixed(\n 2\n )} pressures target`,\n };\n }\n\n const discounted = trustDiscount(negate(source), Math.abs(weight));\n return {\n opinion: cumulativeFusion(target, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(\n 2\n )}) from source at ${project(source).toFixed(2)}`,\n };\n}\n\nexport function applyNegativeEvidence(\n source: Opinion,\n target: Opinion,\n weight: number\n): PropagationResult {\n const discounted = trustDiscount(negate(source), Math.abs(weight));\n return {\n opinion: cumulativeFusion(target, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`,\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/v1/operations/subjectiveLogic/index.ts","../../../../src/v1/operations/dynamics/defeat.ts"],"names":[],"mappings":"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","file":"defeat.js","sourcesContent":["import type { SLOpinion } from \"../../types\";\n\nexport function mkOpinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n const b = Number.isFinite(belief) ? Math.max(0, belief) : 0;\n const d = Number.isFinite(disbelief) ? Math.max(0, disbelief) : 0;\n const u = Number.isFinite(uncertainty) ? Math.max(0, uncertainty) : 0;\n const a = Math.max(0, Math.min(1, baseRate));\n const sum = b + d + u;\n\n if (sum === 0) {\n return { b: 0, d: 0, u: 1, a } as SLOpinion;\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n } as SLOpinion;\n}\n\nexport const opinion = mkOpinion;\n\nexport function vacuous(baseRate: number): SLOpinion {\n return mkOpinion(0, 0, 1, baseRate);\n}\n\nexport function dogmatic(probability: number, baseRate: number): SLOpinion {\n const p = Math.max(0, Math.min(1, probability));\n return mkOpinion(p, 1 - p, 0, baseRate);\n}\n\nexport function project(o: SLOpinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: SLOpinion): \"high\" | \"medium\" | \"low\" {\n const projected = project(o);\n if (o.u > 0.5) {\n return \"low\";\n }\n if (projected >= 0.8 && o.u < 0.2) {\n return \"high\";\n }\n if (projected >= 0.6) {\n return \"medium\";\n }\n return \"low\";\n}\n\nexport function cumulativeFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (left.u * right.u) / k,\n (left.a + right.a) / 2\n );\n}\n\nexport function averagingFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (2 * left.u * right.u) / k,\n (left.a + right.a) / 2\n );\n}\n\nexport function trustDiscount(sourceOpinion: SLOpinion, trust: number): SLOpinion {\n const weight = Math.max(0, Math.min(1, Math.abs(trust)));\n return opinion(\n weight * sourceOpinion.b,\n weight * sourceOpinion.d,\n 1 - weight * (sourceOpinion.b + sourceOpinion.d),\n sourceOpinion.a\n );\n}\n\nconst EPSILON = 1e-9;\n\nfunction childBaseRateFallback(\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number | undefined\n): number {\n if (fallbackBaseRate !== undefined) {\n return Math.max(0, Math.min(1, fallbackBaseRate));\n }\n\n if (Math.abs(ifTrue.a - ifFalse.a) <= EPSILON) {\n return ifTrue.a;\n }\n\n return (ifTrue.a + ifFalse.a) / 2;\n}\n\nfunction computeConditionalDeductionBaseRate(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number\n): number {\n const denominator =\n 1 - opinionA.a * ifTrue.u - (1 - opinionA.a) * ifFalse.u;\n\n if (ifTrue.u + ifFalse.u < 2 - EPSILON && Math.abs(denominator) > EPSILON) {\n const baseRate =\n (opinionA.a * ifTrue.b + (1 - opinionA.a) * ifFalse.b) / denominator;\n if (baseRate >= -EPSILON && baseRate <= 1 + EPSILON) {\n return Math.max(0, Math.min(1, baseRate));\n }\n }\n\n return fallbackBaseRate;\n}\n\nfunction safeCorrectionTerm(\n numerator: number,\n denominator: number\n): number | undefined {\n if (Math.abs(denominator) <= EPSILON) {\n return undefined;\n }\n\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(0, value);\n}\n\nexport function conditionalDeduction(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate?: number\n): SLOpinion {\n const fallbackChildBaseRate = childBaseRateFallback(\n ifTrue,\n ifFalse,\n fallbackBaseRate\n );\n const childBaseRate = computeConditionalDeductionBaseRate(\n opinionA,\n ifTrue,\n ifFalse,\n fallbackChildBaseRate\n );\n const projectedAntecedent = project(opinionA);\n const projectedAntecedentComplement = 1 - projectedAntecedent;\n const intermediateBelief =\n opinionA.b * ifTrue.b +\n opinionA.d * ifFalse.b +\n opinionA.u * (ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a));\n const intermediateDisbelief =\n opinionA.b * ifTrue.d +\n opinionA.d * ifFalse.d +\n opinionA.u * (ifTrue.d * opinionA.a + ifFalse.d * (1 - opinionA.a));\n const intermediateUncertainty =\n opinionA.b * ifTrue.u +\n opinionA.d * ifFalse.u +\n opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedVacuousDeduction =\n ifTrue.b * opinionA.a +\n ifFalse.b * (1 - opinionA.a) +\n childBaseRate *\n (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedConditionalA =\n ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);\n let correction = 0;\n\n if (\n (ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d) ||\n (ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d)\n ) {\n correction = 0;\n } else if (ifTrue.b > ifFalse.b && ifTrue.d <= ifFalse.d) {\n const beliefGap = ifTrue.b - ifFalse.b;\n const disbeliefGap = ifFalse.d - ifTrue.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedent * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,\n projectedAntecedentComplement * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedent * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedentComplement * (1 - childBaseRate)\n ) ?? 0;\n }\n } else {\n const beliefGap = ifFalse.b - ifTrue.b;\n const disbeliefGap = ifTrue.d - ifFalse.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateDisbelief - ifTrue.d) *\n beliefGap,\n projectedAntecedent * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedentComplement * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedent * (1 - childBaseRate)\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n opinionA.a *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedentComplement * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n }\n }\n\n return opinion(\n intermediateBelief - childBaseRate * correction,\n intermediateDisbelief - (1 - childBaseRate) * correction,\n intermediateUncertainty + correction,\n childBaseRate\n );\n}\n\n/**\n * Abductive inference over a conditional.\n * Given an opinion on Y and conditionals P(Y|X), P(Y|~X), infer an opinion on X.\n */\nexport function conditionalAbduction(\n opinionY: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n baseRateX: number\n): SLOpinion {\n const priorX = Math.max(0, Math.min(1, baseRateX));\n const probabilityY = project(opinionY);\n const probabilityGivenTrue = project(ifTrue);\n const probabilityGivenFalse = project(ifFalse);\n\n const posteriorIfYDenominator =\n probabilityGivenTrue * priorX +\n probabilityGivenFalse * (1 - priorX);\n const posteriorIfY =\n posteriorIfYDenominator === 0\n ? priorX\n : (probabilityGivenTrue * priorX) / posteriorIfYDenominator;\n\n const posteriorIfNotYDenominator =\n (1 - probabilityGivenTrue) * priorX +\n (1 - probabilityGivenFalse) * (1 - priorX);\n const posteriorIfNotY =\n posteriorIfNotYDenominator === 0\n ? priorX\n : ((1 - probabilityGivenTrue) * priorX) / posteriorIfNotYDenominator;\n\n const projectedX =\n probabilityY * posteriorIfY + (1 - probabilityY) * posteriorIfNotY;\n const uncertainty = Math.max(\n opinionY.u * 0.5,\n probabilityY * ifTrue.u + (1 - probabilityY) * ifFalse.u\n );\n\n return opinion(\n projectedX * (1 - uncertainty),\n (1 - projectedX) * (1 - uncertainty),\n uncertainty,\n priorX\n );\n}\n\nexport function negate(o: SLOpinion): SLOpinion {\n return mkOpinion(o.d, o.b, o.u, 1 - o.a);\n}\n\nexport function constraintFusion(\n left: SLOpinion,\n right: SLOpinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: SLOpinion; o2: SLOpinion } {\n if (mode === \"redistribute\") {\n const leftProjected = project(left);\n const rightProjected = project(right);\n const total = leftProjected + rightProjected;\n\n if (total <= 1) {\n return { o1: left, o2: right };\n }\n\n const scale = 1 / total;\n return {\n o1: opinion(\n left.b * scale,\n left.d + left.b * (1 - scale),\n left.u,\n left.a\n ),\n o2: opinion(\n right.b * scale,\n right.d + right.b * (1 - scale),\n right.u,\n right.a\n ),\n };\n }\n\n const pressureLeft = right.b * 0.5;\n const pressureRight = left.b * 0.5;\n\n return {\n o1: opinion(\n left.b - pressureLeft * 0.3,\n left.d + pressureLeft * 0.3,\n left.u,\n left.a\n ),\n o2: opinion(\n right.b - pressureRight * 0.3,\n right.d + pressureRight * 0.3,\n right.u,\n right.a\n ),\n };\n}\n\nexport function evidenceBalance(o: SLOpinion): number {\n const total = o.b + o.d;\n if (total === 0) {\n return 0;\n }\n return (o.b - o.d) / total;\n}\n\nexport function areTensioned(left: SLOpinion, right: SLOpinion): boolean {\n return (\n project(left) > 0.5 &&\n project(right) > 0.5 &&\n (left.d > 0.2 || right.d > 0.2)\n );\n}\n\nexport function informationGain(o: SLOpinion): number {\n if (o.u === 0) {\n return 0;\n }\n if (o.u === 1) {\n return 1;\n }\n return o.u * (1 - Math.abs(o.b - o.d));\n}\n","import type { EdgeMetadata, Opinion, PropagationResult } from \"../../types\";\nimport {\n constraintFusion,\n cumulativeFusion,\n mkOpinion,\n negate,\n project,\n trustDiscount,\n} from \"../subjectiveLogic\";\n\nexport function applyNegativeSupport(\n source: Opinion,\n target: Opinion,\n weight: number,\n metadata: EdgeMetadata = {}\n): PropagationResult {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n if (metadata.constraint === \"xor\") {\n const result = constraintFusion(\n sourceOpinion,\n targetOpinion,\n metadata.normalization ?? \"pressure\"\n );\n return {\n opinion: result.o2,\n operator: \"constraint_fusion\",\n rationale: `XOR constraint: source belief at ${project(\n sourceOpinion\n ).toFixed(2)} pressures target`,\n };\n }\n\n const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n}\n\nexport function applyNegativeEvidence(\n source: Opinion,\n target: Opinion,\n weight: number\n): PropagationResult {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`,\n };\n}\n"]}
@@ -1,8 +1,8 @@
1
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));
2
+ function mkOpinion(belief, disbelief, uncertainty, baseRate) {
3
+ const b = Number.isFinite(belief) ? Math.max(0, belief) : 0;
4
+ const d = Number.isFinite(disbelief) ? Math.max(0, disbelief) : 0;
5
+ const u = Number.isFinite(uncertainty) ? Math.max(0, uncertainty) : 0;
6
6
  const a = Math.max(0, Math.min(1, baseRate));
7
7
  const sum = b + d + u;
8
8
  if (sum === 0) {
@@ -15,8 +15,9 @@ function opinion(belief, disbelief, uncertainty, baseRate = 0.5) {
15
15
  a
16
16
  };
17
17
  }
18
- function vacuous(baseRate = 0.5) {
19
- return { b: 0, d: 0, u: 1, a: baseRate };
18
+ var opinion = mkOpinion;
19
+ function vacuous(baseRate) {
20
+ return mkOpinion(0, 0, 1, baseRate);
20
21
  }
21
22
  function project(o) {
22
23
  return o.b + o.a * o.u;
@@ -159,7 +160,7 @@ function conditionalDeduction(opinionA, ifTrue, ifFalse, fallbackBaseRate) {
159
160
  );
160
161
  }
161
162
  function negate(o) {
162
- return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };
163
+ return mkOpinion(o.d, o.b, o.u, 1 - o.a);
163
164
  }
164
165
  function constraintFusion(left, right, mode = "pressure") {
165
166
  if (mode === "redistribute") {
@@ -205,7 +206,14 @@ function constraintFusion(left, right, mode = "pressure") {
205
206
 
206
207
  // src/v1/operations/dynamics/cascade.ts
207
208
  function dampedDependencyOpinion(dependencyOpinion, beliefOpinion, mode = "continuous", threshold = 0.3) {
208
- const dependencyProjection = project(dependencyOpinion);
209
+ const dependencyProjection = project(
210
+ mkOpinion(
211
+ dependencyOpinion.b,
212
+ dependencyOpinion.d,
213
+ dependencyOpinion.u,
214
+ dependencyOpinion.a
215
+ )
216
+ );
209
217
  if (mode === "threshold") {
210
218
  if (dependencyProjection < threshold) {
211
219
  return opinion(
@@ -230,40 +238,49 @@ function dampedDependencyCascade(dependencyOpinion, beliefOpinion, mode = "conti
230
238
  opinion: dampedDependencyOpinion(dependencyOpinion, beliefOpinion, mode),
231
239
  operator: "dependency_cascade",
232
240
  rationale: `Damped dependency cascade (${mode}): prerequisite at ${project(
233
- dependencyOpinion
241
+ mkOpinion(
242
+ dependencyOpinion.b,
243
+ dependencyOpinion.d,
244
+ dependencyOpinion.u,
245
+ dependencyOpinion.a
246
+ )
234
247
  ).toFixed(2)}`
235
248
  };
236
249
  }
237
250
 
238
251
  // src/v1/operations/dynamics/defeat.ts
239
252
  function applyNegativeSupport(source, target, weight, metadata = {}) {
253
+ const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
254
+ const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
240
255
  if (metadata.constraint === "xor") {
241
256
  const result = constraintFusion(
242
- source,
243
- target,
257
+ sourceOpinion,
258
+ targetOpinion,
244
259
  metadata.normalization ?? "pressure"
245
260
  );
246
261
  return {
247
262
  opinion: result.o2,
248
263
  operator: "constraint_fusion",
249
- rationale: `XOR constraint: source belief at ${project(source).toFixed(
250
- 2
251
- )} pressures target`
264
+ rationale: `XOR constraint: source belief at ${project(
265
+ sourceOpinion
266
+ ).toFixed(2)} pressures target`
252
267
  };
253
268
  }
254
- const discounted = trustDiscount(negate(source), Math.abs(weight));
269
+ const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));
255
270
  return {
256
- opinion: cumulativeFusion(target, discounted),
271
+ opinion: cumulativeFusion(targetOpinion, discounted),
257
272
  operator: "cumulative_fusion",
258
273
  rationale: `Contradicting evidence (weight=${weight.toFixed(
259
274
  2
260
- )}) from source at ${project(source).toFixed(2)}`
275
+ )}) from source at ${project(sourceOpinion).toFixed(2)}`
261
276
  };
262
277
  }
263
278
  function applyNegativeEvidence(source, target, weight) {
264
- const discounted = trustDiscount(negate(source), Math.abs(weight));
279
+ const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
280
+ const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
281
+ const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));
265
282
  return {
266
- opinion: cumulativeFusion(target, discounted),
283
+ opinion: cumulativeFusion(targetOpinion, discounted),
267
284
  operator: "cumulative_fusion",
268
285
  rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`
269
286
  };
@@ -274,28 +291,32 @@ var EDGE_PROPAGATION_RULES = {
274
291
  supports: {
275
292
  direction: "outgoing",
276
293
  handler: (source, target, weight, metadata) => {
294
+ const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
295
+ const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
277
296
  if (weight < 0) {
278
- return applyNegativeSupport(source, target, weight, metadata);
297
+ return applyNegativeSupport(sourceOpinion, targetOpinion, weight, metadata);
279
298
  }
280
- const discounted = trustDiscount(source, weight);
299
+ const discounted = trustDiscount(sourceOpinion, weight);
281
300
  return {
282
- opinion: cumulativeFusion(target, discounted),
301
+ opinion: cumulativeFusion(targetOpinion, discounted),
283
302
  operator: "cumulative_fusion",
284
303
  rationale: `Supporting evidence (weight=${weight.toFixed(
285
304
  2
286
- )}) from source at ${project(source).toFixed(2)}`
305
+ )}) from source at ${project(sourceOpinion).toFixed(2)}`
287
306
  };
288
307
  }
289
308
  },
290
309
  informs: {
291
310
  direction: "outgoing",
292
311
  handler: (source, target, weight) => {
312
+ const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
313
+ const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
293
314
  if (weight < 0) {
294
- return applyNegativeEvidence(source, target, weight);
315
+ return applyNegativeEvidence(sourceOpinion, targetOpinion, weight);
295
316
  }
296
- const discounted = trustDiscount(source, Math.abs(weight));
317
+ const discounted = trustDiscount(sourceOpinion, Math.abs(weight));
297
318
  return {
298
- opinion: cumulativeFusion(target, discounted),
319
+ opinion: cumulativeFusion(targetOpinion, discounted),
299
320
  operator: "cumulative_fusion",
300
321
  rationale: `Supporting evidence (weight=${weight.toFixed(2)})`
301
322
  };
@@ -304,23 +325,35 @@ var EDGE_PROPAGATION_RULES = {
304
325
  depends_on: {
305
326
  direction: "incoming",
306
327
  handler: (source, target, _weight, metadata) => {
328
+ const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
329
+ const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
307
330
  if (metadata.conditionalA && metadata.conditionalNotA) {
308
331
  return {
309
332
  opinion: conditionalDeduction(
310
- source,
311
- metadata.conditionalA,
312
- metadata.conditionalNotA,
313
- target.a
333
+ sourceOpinion,
334
+ mkOpinion(
335
+ metadata.conditionalA.b,
336
+ metadata.conditionalA.d,
337
+ metadata.conditionalA.u,
338
+ metadata.conditionalA.a
339
+ ),
340
+ mkOpinion(
341
+ metadata.conditionalNotA.b,
342
+ metadata.conditionalNotA.d,
343
+ metadata.conditionalNotA.u,
344
+ metadata.conditionalNotA.a
345
+ ),
346
+ targetOpinion.a
314
347
  ),
315
348
  operator: "conditional_deduction",
316
349
  rationale: `Conditional deduction: prerequisite at ${project(
317
- source
350
+ sourceOpinion
318
351
  ).toFixed(2)}`
319
352
  };
320
353
  }
321
354
  return dampedDependencyCascade(
322
- source,
323
- target,
355
+ sourceOpinion,
356
+ targetOpinion,
324
357
  metadata.propagation ?? "continuous"
325
358
  );
326
359
  }