/**
 * 文档治理 — 问题二十一 核心实现。
 *
 * 职责:
 * - 制品策略定义（允许/禁止内容、事实源、更新触发条件）
 * - 设计文档准入校验（proposed/accepted_in_memo 不得写入正式设计文档）
 * - 禁止内容合规检查
 * - 注册表与设计文档状态冲突检测
 * - 备忘录决策停滞检测
 */
// ── 内置制品策略 ──
export const BUILTIN_ARTIFACT_POLICIES = [
    {
        artifact: "design_doc",
        allowed_content: ["产品定位和设计目标", "架构分层和核心数据流", "能力状态分层和强制层准入契约", "治理原则、风险边界和人工主权规则"],
        forbidden_content: ["施工日志", "测试数量流水账", "Prompt 模板", "frontmatter schema", "安装命令细节", "文件路径级修复清单", "函数名级实现说明"],
        source_of_truth_for: ["长期稳定的设计事实"],
        update_trigger: ["已验证的设计变更"],
    },
    {
        artifact: "memo",
        allowed_content: ["真实问题记录", "讨论过程和采纳方案", "待落地修复方向"],
        forbidden_content: ["伪装为正式事实"],
        source_of_truth_for: ["决策讨论追溯"],
        update_trigger: ["讨论/方案变更"],
    },
    {
        artifact: "readme",
        allowed_content: ["安装", "初始化", "命令参数", "使用方式", "当前可用能力", "风险提示"],
        forbidden_content: ["内部治理推理", "设计原理"],
        source_of_truth_for: ["用户使用指南"],
        update_trigger: ["命令变更", "能力状态变更"],
    },
    {
        artifact: "contract_registry",
        allowed_content: ["契约状态", "准入条件", "证据文件"],
        forbidden_content: ["施工日志"],
        source_of_truth_for: ["契约状态事实源"],
        update_trigger: ["契约注册/变更"],
    },
    {
        artifact: "capability_registry",
        allowed_content: ["能力状态", "准入条件", "证据文件"],
        forbidden_content: ["施工日志"],
        source_of_truth_for: ["能力状态事实源"],
        update_trigger: ["能力状态变更"],
    },
    {
        artifact: "knowledge_templates",
        allowed_content: ["知识模板格式和示例"],
        forbidden_content: [],
        source_of_truth_for: ["知识模板格式"],
        update_trigger: ["模板 schema 变更"],
    },
    {
        artifact: "issue_pr",
        allowed_content: ["修复过程", "阶段记录", "审查发现"],
        forbidden_content: [],
        source_of_truth_for: ["修复记录"],
        update_trigger: ["修复/审查"],
    },
    {
        artifact: "ci_report",
        allowed_content: ["测试数量和覆盖矩阵"],
        forbidden_content: [],
        source_of_truth_for: ["测试报告"],
        update_trigger: ["CI 运行"],
    },
];
// ── 内部工具函数 ──
/** 生成治理发现 ID */
function generateFindingId(prefix, index) {
    return `doc-gov-${prefix}-${String(index).padStart(4, "0")}`;
}
/** 计算两个 ISO 日期字符串之间的天数差 */
function daysBetween(a, b) {
    const ms = Math.abs(new Date(b).getTime() - new Date(a).getTime());
    return Math.floor(ms / (1000 * 60 * 60 * 24));
}
// ── 核心校验函数 ──
/**
 * 校验设计文档准入资格。
 *
 * 只有 "verified" 或 "design_doc_eligible" 状态可以写入正式设计文档。
 * "proposed" 或 "accepted_in_memo" 状态不得进入正式设计文档（硬拒绝）。
 * 必须提供证据引用。
 */
export function validateDesignDocEligibility(eligibility) {
    const { doc_eligibility_status, evidence_refs } = eligibility;
    // 硬拒绝：未达准入资格的状态
    const hardFailStatuses = [
        "proposed",
        "accepted_in_memo",
    ];
    if (hardFailStatuses.includes(doc_eligibility_status)) {
        return {
            allowed: false,
            reason: `决策 ${eligibility.decision_id} 状态为 "${doc_eligibility_status}"，尚未通过验证，不得写入正式设计文档。请先通过验证流程将状态推进至 "verified" 或 "design_doc_eligible"。`,
        };
    }
    // 硬拒绝：无证据引用
    if (!evidence_refs || evidence_refs.length === 0) {
        return {
            allowed: false,
            reason: `决策 ${eligibility.decision_id} 缺少证据引用（evidence_refs），无法确认准入资格。`,
        };
    }
    // 已失效的决策不得写入
    if (doc_eligibility_status === "superseded") {
        return {
            allowed: false,
            reason: `决策 ${eligibility.decision_id} 已被替代（superseded），不得写入正式设计文档。`,
        };
    }
    // 被拒绝的决策不得写入
    if (doc_eligibility_status === "rejected") {
        return {
            allowed: false,
            reason: `决策 ${eligibility.decision_id} 已被拒绝（rejected），不得写入正式设计文档。`,
        };
    }
    // 允许：verified、design_doc_eligible、implemented 均可
    return {
        allowed: true,
        reason: `决策 ${eligibility.decision_id} 状态为 "${doc_eligibility_status}"，准入资格校验通过（${evidence_refs.length} 条证据）。`,
    };
}
/**
 * 检查文档内容合规性 — 扫描禁止内容模式。
 *
 * 对每个匹配的禁止模式生成一条发现。
 * 如果传入自定义 forbiddenPatterns，以自定义列表为准；
 * 否则使用内置制品策略中该 artifact 类型的禁止列表。
 */
export function checkDocContentCompliance(artifactType, content, forbiddenPatterns) {
    const findings = [];
    // 未传入自定义模式时，从内置策略查找
    const patterns = forbiddenPatterns ??
        BUILTIN_ARTIFACT_POLICIES.find((p) => p.artifact === artifactType)?.forbidden_content ??
        [];
    for (let i = 0; i < patterns.length; i++) {
        const pattern = patterns[i];
        if (content.includes(pattern)) {
            findings.push({
                id: generateFindingId("content", i),
                severity: "hard_fail",
                rule: "forbidden_content",
                artifact_type: artifactType,
                message_zh: `"${artifactType}" 包含禁止内容 "${pattern}"。请将其移除或迁移至合适的制品类型。`,
            });
        }
    }
    return findings;
}
/**
 * 检查注册表与设计文档之间的状态冲突。
 *
 * 注册表为事实源：如果注册表中某策略为 advisory（建议级），
 * 但设计文档中声称该策略为 enforced（强制级），则产生硬拒绝发现。
 */
export function checkRegistryDesignDocConflict(registryState, designDocState) {
    // 事实源为 advisory 但设计文档声称 enforced => 硬拒绝
    if (registryState === "advisory" && designDocState === "enforced") {
        return {
            id: generateFindingId("reg-conflict", 0),
            severity: "hard_fail",
            rule: "registry_doc_mismatch",
            artifact_type: "design_doc",
            message_zh: `设计文档声称策略状态为 "enforced"（强制），但注册表（事实源）记录为 "advisory"（建议）。设计文档必须与注册表保持一致。`,
        };
    }
    // 事实源为 deprecated/removed 但设计文档仍声称 enforced/advisory => 警告
    if ((registryState === "deprecated" || registryState === "removed") &&
        (designDocState === "enforced" || designDocState === "advisory")) {
        return {
            id: generateFindingId("reg-conflict", 1),
            severity: "warning",
            rule: "registry_doc_mismatch",
            artifact_type: "design_doc",
            message_zh: `设计文档声称策略状态为 "${designDocState}"，但注册表记录为 "${registryState}"。设计文档可能需要同步更新。`,
        };
    }
    // 事实源为 experimental 但设计文档声称 enforced => 警告
    if (registryState === "experimental" && designDocState === "enforced") {
        return {
            id: generateFindingId("reg-conflict", 2),
            severity: "warning",
            rule: "registry_doc_mismatch",
            artifact_type: "design_doc",
            message_zh: `设计文档声称策略状态为 "enforced"（强制），但注册表记录为 "experimental"（实验性）。请确认是否应降级为建议级或等待实验验证。`,
        };
    }
    return null;
}
/**
 * 检查备忘录决策停滞 — accepted_in_memo 状态超过阈值未推进。
 *
 * 这些决策在备忘录中被接受，但长期未推进到 verified 或 design_doc_eligible，
 * 可能意味着遗忘或阻塞，需要提醒开发者关注。
 */
export function checkAcceptedMemoStaleness(eligibilities, staleThresholdDays) {
    const findings = [];
    const now = new Date();
    for (let i = 0; i < eligibilities.length; i++) {
        const e = eligibilities[i];
        // 仅检查 accepted_in_memo 状态
        if (e.doc_eligibility_status !== "accepted_in_memo") {
            continue;
        }
        // 需要通过 evidence_refs 中的时间信息判断停滞
        // 如果没有证据引用或无法解析时间，跳过（由其他规则覆盖）
        if (!e.evidence_refs || e.evidence_refs.length === 0) {
            findings.push({
                id: generateFindingId("stale", i),
                severity: "warning",
                rule: "memo_stale_no_evidence",
                artifact_type: "memo",
                message_zh: `决策 ${e.decision_id} 处于 "accepted_in_memo" 状态但缺少证据引用，无法评估停滞时间。`,
            });
            continue;
        }
        // 使用最早的证据引用作为接受时间基准
        // evidence_refs 通常包含时间戳格式（如 ISO 日期字符串或包含日期的引用）
        const earliestRef = e.evidence_refs[0];
        let acceptedDate = null;
        // 尝试解析为 ISO 日期
        const parsed = Date.parse(earliestRef);
        if (!isNaN(parsed)) {
            acceptedDate = new Date(parsed);
        }
        if (!acceptedDate) {
            // 无法从证据引用解析时间，跳过此条
            continue;
        }
        const daysElapsed = daysBetween(acceptedDate.toISOString(), now.toISOString());
        if (daysElapsed > staleThresholdDays) {
            findings.push({
                id: generateFindingId("stale", i),
                severity: daysElapsed > staleThresholdDays * 2 ? "hard_fail" : "warning",
                rule: "memo_staleness",
                artifact_type: "memo",
                message_zh: `决策 ${e.decision_id} 已在 "accepted_in_memo" 状态停留 ${daysElapsed} 天（阈值 ${staleThresholdDays} 天），尚未推进到验证阶段。请检查是否需要推进或关闭。`,
                evidence_ref: earliestRef,
            });
        }
    }
    return findings;
}
//# sourceMappingURL=documentation_governance.js.map