// engine/challenge-prioritizer.ts — SPEC-338
// Ranks failure scenarios by relevance to the specific spec type/target
// and selects the top-3 most critical ones.
// --- Probability weight map (0-1) ---
const PROBABILITY_WEIGHT = {
    low: 0.25,
    medium: 0.55,
    high: 1.0,
};
// --- Impact weight map (0-1) ---
const IMPACT_WEIGHT = {
    low: 0.1,
    medium: 0.35,
    high: 0.65,
    critical: 1.0,
};
/** Keywords that boost relevance when they appear in the scenario text. */
const SPEC_TYPE_KEYWORDS = {
    feature: ['data', 'user', 'input', 'validation', 'state'],
    bugfix: ['regression', 'edge case', 'null', 'undefined', 'race'],
    refactor: ['interface', 'contract', 'compatibility', 'migration', 'deprecat'],
    architecture: ['coupling', 'blast radius', 'rollback', 'migration', 'service'],
    spike: ['timeout', 'external', 'rate limit', 'api', 'latency'],
};
const SPEC_TARGET_KEYWORDS = {
    backend: ['database', 'concurrency', 'transaction', 'queue', 'retry'],
    frontend: ['render', 'state', 'ux', 'loading', 'offline'],
    fullstack: ['sync', 'consistency', 'cache', 'session', 'race'],
    mobile: ['offline', 'battery', 'network', 'crash', 'permission'],
    infrastructure: ['deployment', 'rollback', 'network', 'config', 'secret'],
};
/**
 * Compute a relevance score (0-100) for a scenario given the spec's type and target.
 * Formula: base = probability * impact (0-1), boosted by keyword match (up to +30 points).
 */
export function computeRelevanceScore(scenario, spec) {
    const probWeight = PROBABILITY_WEIGHT[scenario.probability];
    const impactWeight = IMPACT_WEIGHT[scenario.impact];
    // Base score: probability * impact, scaled to 0-70
    const base = probWeight * impactWeight * 70;
    // Keyword boost: up to +30
    const lower = scenario.scenario.toLowerCase();
    const typeKeywords = SPEC_TYPE_KEYWORDS[spec.type] ?? [];
    const targetKeywords = SPEC_TARGET_KEYWORDS[spec.target] ?? [];
    const allKeywords = [...typeKeywords, ...targetKeywords];
    const matchCount = allKeywords.filter((kw) => lower.includes(kw)).length;
    const maxKeywords = Math.max(allKeywords.length, 1);
    const boost = (matchCount / maxKeywords) * 30;
    return Math.round(Math.min(base + boost, 100));
}
/**
 * Given a list of failure scenarios, assign relevanceScore to each and return
 * the top-3 ranked by score descending.
 * Always returns exactly 3 items (or fewer if scenarios has < 3 entries).
 */
export function prioritizeScenarios(scenarios, spec) {
    const scored = scenarios.map((s) => ({
        ...s,
        relevanceScore: computeRelevanceScore(s, spec),
    }));
    scored.sort((a, b) => b.relevanceScore - a.relevanceScore);
    return scored.slice(0, 3).map((s, idx) => ({
        ...s,
        rank: idx + 1,
    }));
}
/**
 * Build the "must address" summary prefix that leads with the top-3 scenarios.
 */
export function buildPrioritizedSummary(top3) {
    if (top3.length === 0) {
        return '';
    }
    const lines = top3.map((s) => `${s.rank}. ${s.scenario}`);
    return `Here are the 3 things you MUST address before coding:\n${lines.join('\n')}`;
}
//# sourceMappingURL=challenge-prioritizer.js.map