#pragma once // Step 546: Confidence Calibration for Constrained Paths #include #include #include struct CalibrationSample { std::string route; bool success = false; bool postApplyFailure = false; }; struct CalibratedConfidence { double adjustedConfidence = 0.0; std::string recommendedRoute; std::map routeScores; }; class ConstrainedConfidenceCalibrator { public: static CalibratedConfidence calibrate( double baseConfidence, const std::map& historicalSuccesses, const std::map& historicalAttempts, const std::map& historicalPostApplyFailures, const std::string& preferredRoute) { CalibratedConfidence out; out.routeScores["deterministic_template"] = scoreFor("deterministic_template", baseConfidence, historicalSuccesses, historicalAttempts, historicalPostApplyFailures); out.routeScores["constrained_worker"] = scoreFor("constrained_worker", baseConfidence, historicalSuccesses, historicalAttempts, historicalPostApplyFailures); out.routeScores["general_worker"] = scoreFor("general_worker", baseConfidence, historicalSuccesses, historicalAttempts, historicalPostApplyFailures); // Mild preference bias only if route is not heavily penalized. if (!preferredRoute.empty()) { out.routeScores[preferredRoute] += 0.03; } for (auto& kv : out.routeScores) { kv.second = clamp(kv.second); } out.recommendedRoute = bestRoute(out.routeScores); out.adjustedConfidence = clamp(out.routeScores[out.recommendedRoute]); return out; } private: static double scoreFor(const std::string& route, double base, const std::map& successes, const std::map& attempts, const std::map& postApplyFailures) { const int s = lookup(successes, route); const int a = lookup(attempts, route); const int f = lookup(postApplyFailures, route); double successRate = (a > 0) ? (double)s / (double)a : 0.5; double failurePenalty = (a > 0) ? (double)f / (double)a : 0.0; double score = base; score += 0.35 * (successRate - 0.5); score -= 0.45 * failurePenalty; // Repeated post-apply failures trigger stronger decay. if (f >= 3) score -= 0.10; if (f >= 5) score -= 0.10; return clamp(score); } static int lookup(const std::map& m, const std::string& key) { auto it = m.find(key); return it == m.end() ? 0 : it->second; } static std::string bestRoute(const std::map& scores) { std::string best = "general_worker"; double bestScore = -1.0; for (const auto& kv : scores) { if (kv.second > bestScore) { bestScore = kv.second; best = kv.first; } } return best; } static double clamp(double x) { return std::max(0.0, std::min(1.0, x)); } };