/**
 * 能力状态变更建议 — 基于 escape report 生成 downgrade/disable/promote_blocked/keep 决策。
 * P2-4 范围: 只输出建议，不直接改 registry。
 *
 * 规则来源: 设计方案 7.7.3 降级规则表。
 */
import { debug } from "../core/logger.js";
const CRITICAL_ESCAPE_TYPES = new Set([
    "ai_escape",
    "rule_gap",
    "tool_bug",
]);
const MEDIUM_ESCAPE_TYPES = new Set([
    "weak_test",
    "bad_evidence",
    "human_miss",
]);
const FALSE_POSITIVE_TYPE = "false_positive";
const FALSE_POSITIVE_THRESHOLD = 2;
const RULE_CRITICAL_ESCAPE = {
    rule_id: "R-CE",
    description: "同一 policy_id 出现 1 次严重逃逸 (ai_escape/rule_gap/tool_bug) → enforced→advisory",
    severity: "critical",
};
const RULE_TWO_MEDIUM_7DAYS = {
    rule_id: "R-2M7D",
    description: "7 天内同一 policy_id 出现 2 次中等逃逸 → enforced→advisory",
    severity: "medium",
};
const RULE_REPEATED_FALSE_POSITIVE = {
    rule_id: "R-FP",
    description: `连续 ${FALSE_POSITIVE_THRESHOLD}+ 次误伤 → promote_blocked（暂停 hard block，保留 warning）`,
    severity: "medium",
};
const RULE_STALE_ENFORCED = {
    rule_id: "R-SE",
    description: "advisory/experimental 下仍有逃逸累积 → disable 直到修复",
    severity: "critical",
};
function withinDays(report, days, now) {
    const created = new Date(report.created_at);
    const cutoff = new Date(now.getTime() - days * 24 * 60 * 60 * 1000);
    return created >= cutoff;
}
/**
 * 执行 decideAction 操作
 */
export function decideAction(reports, current_state, policy_id, now = new Date()) {
    debug("能力决策", "decideAction() 开始 — policy_id:", policy_id, "当前状态:", current_state);
    const relevant = reports.filter((r) => r.policy_id === policy_id);
    const criticals = relevant.filter((r) => CRITICAL_ESCAPE_TYPES.has(r.failure_type) && r.capability_action !== "keep");
    const mediumsRecent = relevant.filter((r) => MEDIUM_ESCAPE_TYPES.has(r.failure_type) &&
        r.capability_action !== "keep" &&
        withinDays(r, 7, now));
    const falsePositives = relevant.filter((r) => r.failure_type === FALSE_POSITIVE_TYPE);
    const triggered = [];
    // 规则 R-CE: 1 次严重逃逸 → enforced 降级为 advisory
    if (criticals.length >= 1) {
        triggered.push(RULE_CRITICAL_ESCAPE);
    }
    // 规则 R-2M7D: 7 天内 2 次中等逃逸 → enforced 降级为 advisory
    if (mediumsRecent.length >= 2) {
        triggered.push(RULE_TWO_MEDIUM_7DAYS);
    }
    // 规则 R-FP: 连续误伤 → promote_blocked
    if (falsePositives.length >= FALSE_POSITIVE_THRESHOLD) {
        triggered.push(RULE_REPEATED_FALSE_POSITIVE);
    }
    // 根据触发规则和当前状态确定动作
    if (triggered.length === 0) {
        debug("能力决策", "无触发规则，保持当前状态 —", policy_id);
        return {
            policy_id,
            current_state,
            recommended_action: "keep",
            target_state: current_state,
            reason: `${policy_id} 无可操作逃逸。能力保持 ${current_state}。`,
            evidence_ids: [],
            triggered_rules: [],
        };
    }
    const evidenceIds = [
        ...criticals.map((r) => r.escape_id),
        ...mediumsRecent.map((r) => r.escape_id),
        ...falsePositives.map((r) => r.escape_id),
    ];
    // R-FP 无论当前状态如何都升级为 blocked
    const hasFP = triggered.some((r) => r.rule_id === "R-FP");
    if (current_state === "enforced") {
        // 严重或 2 次以上中等 → 降级为 advisory
        if (triggered.some((r) => r.rule_id === "R-CE" || r.rule_id === "R-2M7D")) {
            debug("能力决策", "enforced→advisory —", policy_id, "触发规则:", triggered.map(r => r.rule_id).join(","));
            return {
                policy_id,
                current_state,
                recommended_action: "downgrade",
                target_state: "advisory",
                reason: `已实施能力 ${policy_id} 触发 ${triggered.map((r) => r.rule_id).join(", ")}。建议降级为 advisory。`,
                evidence_ids: evidenceIds,
                triggered_rules: triggered,
            };
        }
        // 仅误伤 → promote_blocked
        if (hasFP) {
            debug("能力决策", "promote_blocked (enforced) —", policy_id, "误伤次数:", falsePositives.length);
            return {
                policy_id,
                current_state,
                recommended_action: "promote_blocked",
                target_state: "enforced",
                reason: `已实施能力 ${policy_id} 有 ${falsePositives.length} 次误伤。硬性阻止已暂停，保留警告。`,
                evidence_ids: evidenceIds,
                triggered_rules: triggered,
            };
        }
    }
    if (current_state === "advisory" || current_state === "experimental") {
        // 已降级但仍持续累积逃逸 → disable
        if (triggered.some((r) => r.rule_id === "R-CE" || r.rule_id === "R-2M7D")) {
            triggered.push(RULE_STALE_ENFORCED);
            debug("能力决策", current_state, "→ removed (disable) —", policy_id, "持续累积逃逸");
            return {
                policy_id,
                current_state,
                recommended_action: "disable",
                target_state: "removed",
                reason: `${current_state} 能力 ${policy_id} 持续累积逃逸。建议 disable 直到修复。`,
                evidence_ids: evidenceIds,
                triggered_rules: triggered,
            };
        }
        // 仅误伤且处于 advisory/experimental → 仍然 promote_blocked
        if (hasFP) {
            debug("能力决策", "promote_blocked (advisory/experimental) —", policy_id, "状态:", current_state, "误伤次数:", falsePositives.length);
            return {
                policy_id,
                current_state,
                recommended_action: "promote_blocked",
                target_state: current_state,
                reason: `${current_state} 能力 ${policy_id} 有 ${falsePositives.length} 次误伤。升级为 enforced blocked。`,
                evidence_ids: evidenceIds,
                triggered_rules: triggered,
            };
        }
    }
    // removed 状态或未处理: keep
    debug("能力决策", "保持状态 —", policy_id, "当前:", current_state, "已触发规则:", triggered.map(r => r.rule_id).join(","));
    return {
        policy_id,
        current_state,
        recommended_action: "keep",
        target_state: current_state,
        reason: `不建议对 ${policy_id} 进行状态变更（当前: ${current_state}）。`,
        evidence_ids: evidenceIds,
        triggered_rules: triggered,
    };
}
//# sourceMappingURL=capability_action_advisor.js.map