/**
 * User Feedback Contract
 *
 * 用户可见反馈体验结构化契约。
 * 将澄清、进度、降级、失败、人工确认、验证摘要、产物就绪、
 * 交付许可、交付结果、阻塞和完成统一建模为用户可见反馈。
 * 确保 SoloForge 不把 partial / manual_required / degraded 误说成 completed。
 */
import { evaluateUserVisibleOutput, recordCepIntegration } from "../audit/core_experience_principle.js";
import { debug } from "../core/logger.js";
const TOOL_FEEDBACK_MAP = {
    "sf_classify": ["progress", "clarification"],
    "sf_expand": ["clarification", "progress", "artifact_ready", "degradation"],
    "sf_verify": ["verification_summary", "failure", "human_required", "blocked"],
    "sf_review": ["verification_summary", "human_required", "degradation"],
    "sf_learn": ["delivery_readiness", "delivery_result", "blocked", "failure"],
    sf_status: ["progress", "blocked", "human_required"],
    sf_plan: ["artifact_ready", "clarification", "human_required"],
    sf_explore: ["artifact_ready", "human_required"],
    sf_knowledge_audit: ["verification_summary", "degradation"],
    sf_sync_templates: ["progress", "artifact_ready", "human_required", "blocked"],
    sf_contract_check: ["verification_summary", "blocked"],
    sf_debug: ["progress", "failure", "artifact_ready"],
};
/** 获取指定工具允许的反馈类型列表 */
export function getAllowedFeedbackKinds(tool) {
    debug("用户反馈契约", "获取工具允许的反馈类型", tool);
    return TOOL_FEEDBACK_MAP[tool] ?? [];
}
/** 检查指定反馈类型是否允许用于某工具 */
export function isFeedbackKindAllowedForTool(tool, kind) {
    debug("用户反馈契约", "检查反馈类型是否允许", tool, kind);
    return TOOL_FEEDBACK_MAP[tool]?.includes(kind) ?? false;
}
/** 列出所有注册的 SoloForge 工具 */
export function listTools() {
    debug("用户反馈契约", "列出所有工具");
    return Object.keys(TOOL_FEEDBACK_MAP);
}
// ── Kind → 默认严重级别 ──
const KIND_SEVERITY = {
    clarification: "blocking",
    progress: "info",
    degradation: "warning",
    failure: "blocking",
    human_required: "blocking",
    verification_summary: "info",
    artifact_ready: "info",
    delivery_readiness: "info",
    delivery_result: "success",
    blocked: "blocking",
    completed: "success",
};
/** 获取指定反馈类型的默认严重级别 */
export function getDefaultSeverity(kind) {
    debug("用户反馈契约", "获取默认严重级别", kind);
    return KIND_SEVERITY[kind];
}
// ── Kind → 是否需要用户操作 ──
const KIND_REQUIRES_ACTION = {
    clarification: true,
    progress: false,
    degradation: false,
    failure: true,
    human_required: true,
    verification_summary: false,
    artifact_ready: false,
    delivery_readiness: true,
    delivery_result: false,
    blocked: true,
    completed: false,
};
/** 获取指定反馈类型是否默认需要用户操作 */
export function getDefaultRequiresAction(kind) {
    debug("用户反馈契约", "获取默认是否需要用户操作", kind);
    return KIND_REQUIRES_ACTION[kind];
}
// ── 禁用措辞规则 ──
const FORBIDDEN_WORDING = [
    {
        pattern: /已完成/,
        appliesTo: ["artifact_ready", "delivery_readiness"],
        reason: "artifact_ready / delivery_readiness 不得说'已完成'",
    },
    {
        pattern: /已交付/,
        appliesTo: ["delivery_readiness", "artifact_ready"],
        reason: "delivery_readiness / artifact_ready 不得说'已交付'",
    },
    {
        pattern: /完成/,
        appliesTo: ["degradation", "blocked", "failure"],
        reason: "degradation / blocked / failure 不得使用'完成'",
    },
];
/** 检查消息中是否包含禁用措辞 */
export function checkForbiddenWording(message) {
    debug("用户反馈契约", "检查禁用措辞", message.kind);
    const violations = [];
    for (const { pattern, appliesTo, reason } of FORBIDDEN_WORDING) {
        if (appliesTo.includes(message.kind) && (pattern.test(message.title) || pattern.test(message.summary))) {
            violations.push({ forbidden: true, reason });
        }
    }
    return violations;
}
// ── 中文响应模板 ──
/** 获取指定反馈类型的中文状态模板 */
export function getStatusTemplate(kind) {
    debug("用户反馈契约", "获取状态模板", kind);
    const templates = {
        clarification: "需要你确认以下内容。",
        progress: "正在执行中。",
        degradation: "当前降级执行，以下能力未生效。",
        failure: "执行失败，以下是失败证据和建议下一步。",
        human_required: "已完成可自动处理部分，等待你确认。",
        verification_summary: "验证已完成，以下是验证结果。",
        artifact_ready: "产物已生成，当前状态为 draft/verified/accepted。",
        delivery_readiness: "交付条件已满足/未满足，但未执行交付动作。",
        delivery_result: "交付已执行，以下是结果和回滚方式。",
        blocked: "当前已阻塞，需要满足条件才能继续。",
        completed: "任务已完成，以下是验证和风险摘要。",
    };
    return templates[kind];
}
// ── 语言边界: 路径/命令/错误码不得翻译 ──
/** 检测文本是否为技术内容（路径/命令/错误码），不应翻译 */
export function isTechnicalContent(text) {
    debug("用户反馈契约", "检测是否为技术内容", text);
    return /^(\/|\.\/|src\/|tests\/|node_modules\/|npm |npx |git |\.soloforge\/|Error:|ERR_|exit code)/.test(text);
}
// ── 工厂函数 ──
/** 创建用户反馈消息 */
export function createUserFeedbackMessage(params) {
    debug("用户反馈契约", "创建用户反馈消息", params.kind);
    return {
        kind: params.kind,
        task_id: params.task_id,
        severity: params.severity ?? getDefaultSeverity(params.kind),
        title: params.title,
        summary: params.summary,
        verified: params.verified ?? [],
        unverified: params.unverified ?? [],
        risks: params.risks ?? [],
        requires_user_action: params.user_action ? true : getDefaultRequiresAction(params.kind),
        user_action: params.user_action,
        default_recommendation: params.default_recommendation,
        references: params.references ?? [],
    };
}
// ── 详情校验器 ──
/** 验证澄清详情的必填字段 */
export function validateClarificationDetail(detail) {
    debug("用户反馈契约", "验证澄清详情");
    const errors = [];
    if (!detail.blocking_question)
        errors.push("clarification 必须有 blocking_question");
    if (!detail.default_recommendation)
        errors.push("clarification 必须有 default_recommendation");
    if (!detail.impact_if_unanswered)
        errors.push("clarification 必须有 impact_if_unanswered");
    return errors;
}
/** 验证降级详情的必填字段 */
export function validateDegradationDetail(detail) {
    debug("用户反馈契约", "验证降级详情");
    const errors = [];
    if (!detail.component_id)
        errors.push("degradation 必须有 component_id");
    if (!detail.degraded_mode)
        errors.push("degradation 必须有 degraded_mode");
    if (!detail.recovery_hint)
        errors.push("degradation 必须有 recovery_hint");
    return errors;
}
/** 验证失败详情的必填字段 */
export function validateFailureDetail(detail) {
    debug("用户反馈契约", "验证失败详情");
    const errors = [];
    if (!detail.failure_class)
        errors.push("failure 必须有 failure_class");
    if (!detail.next_action)
        errors.push("failure 必须有 next_action");
    return errors;
}
/** 验证人工确认详情的必填字段 */
export function validateHumanRequiredDetail(detail) {
    debug("用户反馈契约", "验证人工确认详情");
    const errors = [];
    if (!detail.decision_scope)
        errors.push("human_required 必须有 decision_scope");
    if (!detail.reason)
        errors.push("human_required 必须有 reason");
    return errors;
}
/** 验证交付结果详情的状态字段 */
export function validateDeliveryResultDetail(detail) {
    debug("用户反馈契约", "验证交付结果详情");
    const errors = [];
    const validStatuses = ["executed", "not_executed", "failed"];
    if (!validStatuses.includes(detail.push_status))
        errors.push("delivery_result push_status 无效");
    if (!validStatuses.includes(detail.deploy_status))
        errors.push("delivery_result deploy_status 无效");
    return errors;
}
/** 验证阻塞详情的必填字段 */
export function validateBlockedDetail(detail) {
    debug("用户反馈契约", "验证阻塞详情");
    const errors = [];
    if (!detail.block_reason)
        errors.push("blocked 必须有 block_reason");
    if (!detail.unblock_condition)
        errors.push("blocked 必须有 unblock_condition");
    if (!detail.recommended_next_action)
        errors.push("blocked 必须有 recommended_next_action");
    return errors;
}
/** 验证完成详情的一致性 */
export function validateCompletedDetail(detail) {
    debug("用户反馈契约", "验证完成详情");
    const errors = [];
    if (detail.unverified.length > 0) {
        detail.unverified.filter(u => !detail.risks.includes(u));
        // completed 允许 unverified 但不得有 blocking unverified (应在 risks 中标记)
    }
    return errors;
}
// ── 交付结果展示 ──
/** 格式化交付操作状态为中文描述 */
export function formatDeliveryActionStatus(label, status) {
    debug("用户反馈契约", "格式化交付操作状态", label, status);
    if (status === "executed")
        return `${label}: 已执行`;
    if (status === "failed")
        return `${label}: 执行失败`;
    return `${label}: 未执行`;
}
/** 构建交付结果的反馈文本 */
export function buildDeliveryResultFeedback(detail) {
    debug("用户反馈契约", "构建交付结果反馈");
    const lines = [];
    lines.push(formatDeliveryActionStatus("commit", detail.commit_hash ? "executed" : "not_executed"));
    if (detail.commit_hash)
        lines.push(`  hash: ${detail.commit_hash}`);
    lines.push(formatDeliveryActionStatus("push", detail.push_status));
    if (detail.pr_url)
        lines.push(`PR: ${detail.pr_url}`);
    lines.push(formatDeliveryActionStatus("deploy", detail.deploy_status));
    if (detail.rollback_ref)
        lines.push(`回滚参考: ${detail.rollback_ref}`);
    return lines.join("\n");
}
// ── 治理校验 ──
/** 验证用户反馈契约合规性，返回治理发现列表 */
export function validateUserFeedbackContract(messages) {
    debug("用户反馈契约", "验证用户反馈契约", "消息数:", messages.length);
    const findings = [];
    for (const msg of messages) {
        // 规则 1: partial/manual_required/degraded 不得说成 completed
        const wordingViolations = checkForbiddenWording(msg);
        for (const v of wordingViolations) {
            if (v.forbidden) {
                findings.push({
                    severity: "hard_fail",
                    rule: "gc-forbidden-wording",
                    kind: msg.kind,
                    message: v.reason,
                });
            }
        }
        // 规则 2: degradation 必须在最终反馈中显式出现
        if (msg.kind === "degradation" && msg.summary.length === 0) {
            findings.push({
                severity: "hard_fail",
                rule: "gc-degradation-hidden",
                kind: msg.kind,
                message: "降级反馈必须包含说明",
            });
        }
        // 规则 3: failed/blocked 必须有 next action
        if ((msg.kind === "failure" || msg.kind === "blocked") && !msg.user_action && !msg.default_recommendation) {
            findings.push({
                severity: "hard_fail",
                rule: "gc-no-next-action",
                kind: msg.kind,
                message: `${msg.kind} 反馈必须包含 next action 或 default_recommendation`,
            });
        }
        // 规则 4: human_required 必须明确确认项
        if (msg.kind === "human_required" && !msg.user_action) {
            findings.push({
                severity: "hard_fail",
                rule: "gc-human-no-action",
                kind: msg.kind,
                message: "human_required 必须明确用户需要确认什么",
            });
        }
        // 规则 5: completed 不能有 blocking unverified
        if (msg.kind === "completed" && msg.unverified.length > 0 && msg.severity !== "success") {
            findings.push({
                severity: "hard_fail",
                rule: "gc-completed-blocking-unverified",
                kind: msg.kind,
                message: "completed 反馈存在 blocking unverified 项",
            });
        }
        // 规则 6: delivery_result 必须列明 commit/push/PR/deploy
        if (msg.kind === "delivery_result" && msg.references.length === 0) {
            findings.push({
                severity: "hard_fail",
                rule: "gc-delivery-no-refs",
                kind: msg.kind,
                message: "delivery_result 必须列出 commit/push/PR/deploy 引用",
            });
        }
        // 规则 7: artifact_ready 必须列明 artifact status
        if (msg.kind === "artifact_ready" && msg.references.length === 0) {
            findings.push({
                severity: "hard_fail",
                rule: "gc-artifact-no-status",
                kind: msg.kind,
                message: "artifact_ready 必须列明 artifact status",
            });
        }
        // 规则 8: severity 与 kind 一致性
        getDefaultSeverity(msg.kind);
        if (msg.kind === "failure" && msg.severity === "info") {
            findings.push({
                severity: "warning",
                rule: "gc-severity-mismatch",
                kind: msg.kind,
                message: `failure 反馈 severity 应为 blocking，当前为 ${msg.severity}`,
            });
        }
        // 规则 9: 中文优先 - title/summary 应包含中文
        const hasChinese = /[一-鿿]/.test(msg.title) || /[一-鿿]/.test(msg.summary);
        if (!hasChinese) {
            findings.push({
                severity: "warning",
                rule: "gc-not-chinese",
                kind: msg.kind,
                message: `用户反馈应中文优先: ${msg.kind}`,
            });
        }
        // 规则 10: verification_summary with unverified+risks = masking
        if (msg.kind === "verification_summary" && msg.unverified.length > 0 && msg.risks.length > 0) {
            findings.push({
                severity: "hard_fail",
                rule: "gc-verification-summary-masking",
                kind: msg.kind,
                message: "verification_summary 存在未验证项和风险但仍汇报，掩盖失败",
            });
        }
    }
    // ── CEP 用户反馈输出质量评估 — 失败必须进入 governance findings ──
    const hasConclusion = messages.some(m => m.title.length > 0);
    const hasSummary = messages.every(m => m.summary.length > 0);
    const hidesFailure = messages.some(m => m.kind === "completed" && m.severity === "blocking");
    const needsActionKinds = ["completed", "blocked", "failure", "human_required", "delivery_readiness"];
    const hasActionableNext = messages.some(m => !needsActionKinds.includes(m.kind) ||
        (m.user_action && m.user_action.length > 0) ||
        (m.default_recommendation && m.default_recommendation.length > 0) ||
        (m.references.length > 0) ||
        (m.kind === "completed" && m.verified.length > 0));
    const hasChinese = messages.some(m => /[一-鿿]/.test(m.title) || /[一-鿿]/.test(m.summary));
    const cepFbResult = evaluateUserVisibleOutput({
        has_conclusion_first: hasConclusion,
        has_clear_summary: hasSummary,
        has_actionable_next_step: hasActionableNext,
        exposes_internal_noise: false,
        hides_critical_failure: hidesFailure,
        chinese_semantic_first: hasChinese,
    });
    // CEP issues → 稳定 rule 映射
    const CEP_RULE_MAP = {
        "用户可见输出未先给结论": { rule: "gc-cep-no-conclusion", severity: "hard_fail" },
        "用户可见输出缺少清晰摘要": { rule: "gc-cep-no-summary", severity: "hard_fail" },
        "用户可见输出缺少可执行的下一步": { rule: "gc-cep-no-next-action", severity: "hard_fail" },
        "用户可见输出暴露内部流水账": { rule: "gc-cep-internal-noise", severity: "warning" },
        "用户可见输出隐藏了关键失败": { rule: "gc-cep-hidden-critical-failure", severity: "hard_fail" },
        "用户可见输出未中文语义优先": { rule: "gc-cep-not-chinese", severity: "hard_fail" },
    };
    for (const issue of cepFbResult.issues_zh) {
        const mapped = CEP_RULE_MAP[issue];
        if (mapped) {
            findings.push({
                severity: mapped.severity,
                rule: mapped.rule,
                message: issue,
            });
        }
    }
    // completed/success 且无下一步 → 要求有非打扰型查验方式
    for (const msg of messages) {
        if (msg.kind === "completed" && msg.severity === "success") {
            const hasVerificationOrRefs = msg.verified.length > 0 || msg.references.length > 0;
            const hasRecommendation = (msg.default_recommendation ?? "").length > 0;
            if (!hasVerificationOrRefs && !hasRecommendation) {
                findings.push({
                    severity: "hard_fail",
                    rule: "gc-cep-completed-no-verification-path",
                    kind: msg.kind,
                    message: "completed success 反馈必须包含 verified/references/default_recommendation 以提供查验方式",
                });
            }
        }
    }
    recordCepIntegration("user_feedback", {
        passed: cepFbResult.passed,
        violations: cepFbResult.issues_zh.map(issue => ({
            principle: "sufficient_evidence_concise_output", severity: "warning",
            reason_zh: issue, evidence_refs: [], required_action: "simplify_output",
        })),
    });
    return findings;
}
//# sourceMappingURL=user_feedback_contract.js.map