UNPKG

@jadermme/orus-core

Version:

ORUS Core Framework - Universal framework for 6 Pillars assessment, domain-agnostic

264 lines 8.63 kB
/** * ORUS Core - Mode Logic * * Pure functions for handling assessment mode transitions and hybrid calculations. * * @remarks * ORUS supports 3 assessment modes: * - subjective: Quick user perception (low confidence) * - objective: Data-driven via domain engines (high confidence) * - hybrid: Combines both (medium confidence) * * This module provides: * - Hybrid score resolution (combining subjective + objective) * - Mode transition validation * - Confidence inference from mode */ /** * Resolves a hybrid score from subjective and objective inputs * * @param params - Hybrid score parameters * @returns Hybrid score result with breakdown * * @remarks * - Pure function: deterministic calculation * - Default strategy: objective_priority (70/30) * - Detects significant discrepancies (> 2 points difference) * - Discrepancies may indicate: * - User perception doesn't match data reality * - Missing context in objective calculation * - Need for user education or data review * * @example * ```typescript * const result = resolveHybridScore({ * subjectiveScore: 4.0, // User feels it's bad * objectiveScore: 7.5, // But data shows it's good * strategy: 'objective_priority' * }); * * // result.hybridScore = 6.55 (weighted toward objective) * // result.discrepancy = 3.5 * // result.hasSignificantDiscrepancy = true * ``` */ export function resolveHybridScore(params) { const { subjectiveScore, objectiveScore, strategy = 'objective_priority', customWeights } = params; // Determine weights based on strategy let weights; switch (strategy) { case 'objective_priority': weights = { objective: 0.7, subjective: 0.3 }; break; case 'balanced': weights = { objective: 0.5, subjective: 0.5 }; break; case 'subjective_priority': weights = { objective: 0.3, subjective: 0.7 }; break; case 'weighted': weights = customWeights || { objective: 0.7, subjective: 0.3 }; break; default: weights = { objective: 0.7, subjective: 0.3 }; } // Calculate weighted average const hybridScore = objectiveScore * weights.objective + subjectiveScore * weights.subjective; // Calculate discrepancy const discrepancy = Math.abs(objectiveScore - subjectiveScore); const hasSignificantDiscrepancy = discrepancy > 2.0; return { hybridScore: Math.round(hybridScore * 10) / 10, strategy, weights, discrepancy: Math.round(discrepancy * 10) / 10, hasSignificantDiscrepancy }; } /** * Infers confidence level from assessment mode * * @param mode - Assessment mode * @returns Typical confidence level for that mode * * @remarks * - Pure function: simple mapping * - Default inference (can be overridden): * - subjective => low confidence * - objective => high confidence * - hybrid => medium confidence * * @example * ```typescript * inferConfidenceFromMode('subjective') // => 'low' * inferConfidenceFromMode('objective') // => 'high' * inferConfidenceFromMode('hybrid') // => 'medium' * ``` */ export function inferConfidenceFromMode(mode) { const modeToConfidence = { subjective: 'low', objective: 'high', hybrid: 'medium' }; return modeToConfidence[mode]; } /** * Validates if a mode transition is allowed * * @param transition - Mode transition to validate * @param dataCompleteness - Current data completeness (0-1) * @returns Validation result * * @remarks * - Pure function: deterministic validation * - Rules: * - subjective -> objective: requires dataCompleteness >= 0.7 * - subjective -> hybrid: requires dataCompleteness >= 0.4 * - objective -> hybrid: always allowed * - hybrid -> objective: requires dataCompleteness >= 0.8 * - Same mode: always allowed (no-op) * - Downgrades (objective -> subjective): always allowed but warned * * @example * ```typescript * const validation = canTransitionMode( * { from: 'subjective', to: 'objective' }, * 0.5 // Only 50% data completeness * ); * * // validation.isValid = false * // validation.reason = "Insufficient data for objective mode" * // validation.recommendations = ["Collect more data...", ...] * ``` */ export function canTransitionMode(transition, dataCompleteness) { const { from, to } = transition; // No transition needed if (from === to) { return { isValid: true, reason: 'No transition needed (same mode)' }; } // Subjective -> Objective if (from === 'subjective' && to === 'objective') { if (dataCompleteness < 0.7) { return { isValid: false, reason: 'Insufficient data for objective mode (requires >= 70% completeness)', recommendations: [ 'Collect more data through domain-specific engines', 'Use hybrid mode as an intermediate step', 'Ensure all required data points are available' ] }; } return { isValid: true, reason: 'Sufficient data available for objective assessment' }; } // Subjective -> Hybrid if (from === 'subjective' && to === 'hybrid') { if (dataCompleteness < 0.4) { return { isValid: false, reason: 'Insufficient data for hybrid mode (requires >= 40% completeness)', recommendations: [ 'Collect basic data points for hybrid calculation', 'Start with partial objective data and subjective input' ] }; } return { isValid: true, reason: 'Sufficient data for hybrid mode' }; } // Hybrid -> Objective if (from === 'hybrid' && to === 'objective') { if (dataCompleteness < 0.8) { return { isValid: false, reason: 'Insufficient data for full objective mode (requires >= 80% completeness)', recommendations: [ 'Complete remaining data collection', 'Verify all objective metrics are available', 'Stay in hybrid mode until data is complete' ] }; } return { isValid: true, reason: 'Data completeness meets objective mode requirements' }; } // Objective -> Hybrid (always allowed) if (from === 'objective' && to === 'hybrid') { return { isValid: true, reason: 'Downgrade to hybrid is always allowed' }; } // Any -> Subjective (downgrade, allowed but warned) if (to === 'subjective') { return { isValid: true, reason: 'Downgrade to subjective mode (warning: loses data-driven insights)', recommendations: [ 'Consider if this downgrade is necessary', 'Objective/hybrid modes provide better accuracy', 'Subjective mode should be temporary' ] }; } // Default: allow transition return { isValid: true, reason: 'Transition allowed' }; } /** * Suggests optimal mode based on data completeness * * @param dataCompleteness - Current data completeness (0-1) * @returns Recommended mode and reason * * @remarks * - Pure function: deterministic recommendation * - Thresholds: * - < 0.4: subjective (insufficient data) * - 0.4-0.7: hybrid (partial data available) * - >= 0.7: objective (sufficient data) * * @example * ```typescript * suggestOptimalMode(0.3) // => { mode: 'subjective', ... } * suggestOptimalMode(0.6) // => { mode: 'hybrid', ... } * suggestOptimalMode(0.9) // => { mode: 'objective', ... } * ``` */ export function suggestOptimalMode(dataCompleteness) { if (dataCompleteness < 0.4) { return { mode: 'subjective', reason: 'Low data completeness - rely on user perception', confidence: 'low' }; } if (dataCompleteness < 0.7) { return { mode: 'hybrid', reason: 'Moderate data completeness - combine data with user input', confidence: 'medium' }; } return { mode: 'objective', reason: 'High data completeness - rely on data-driven assessment', confidence: 'high' }; } //# sourceMappingURL=modeLogic.js.map