import { POLICY_CAPS } from "../config/defaults.js"; import type { AgentFact, Policy, UltraConfig } from "../types.js"; export interface Coverage { duplicateRate: number; uniqueFindings: number; unresolvedCritical: number; contradictions: number; confidenceGain: number; marginalCost: number; remainingBudget?: number } export function effectiveInitial(config: UltraConfig, policy: Policy): number { return Math.min(config.scout.initial, POLICY_CAPS[policy].initialScouts); } export function evaluateCoverage(facts: AgentFact[], unresolvedCritical: number, contradictions: number, confidenceGain: number, marginalCost: number, remainingBudget?: number): Coverage { const seen = new Set(); let duplicates = 0; for (const fact of facts) { const key = fact.claim.trim().toLowerCase().replace(/\s+/g, " "); if (seen.has(key)) duplicates += 1; seen.add(key); } return { duplicateRate: facts.length ? duplicates / facts.length : 0, uniqueFindings: seen.size, unresolvedCritical, contradictions, confidenceGain, marginalCost, remainingBudget }; } export function shouldWiden(coverage: Coverage, policy: Policy, wave: number, estimatedValue: number): boolean { const caps = POLICY_CAPS[policy]; return wave < caps.maxWaves && estimatedValue > 0 && (coverage.remainingBudget ?? Infinity) > 0 && coverage.duplicateRate < 0.5 && (coverage.unresolvedCritical > 0 || coverage.contradictions > 0 || coverage.confidenceGain < 0.2); }