/**
 * 统一契约注册表 — 契约治理验证函数
 *
 * 包含: validateContractRegistry, checkCapabilityContractConflict,
 * validateWorkflowContractRefs
 */
import { getCapability } from "../capability_registry.js";
import { getRegistry } from "./registry_internal.js";
/**
 * 验证契约注册表完整性。
 * 检查: 唯一性、字段完整性、文件存在、状态约束、依赖存在性、capability 冲突等。
 */
export function validateContractRegistry(existingFiles) {
    const findings = [];
    const entries = [...getRegistry().values()];
    const idSet = new Set();
    for (const entry of entries) {
        // 1. contract_id 唯一且非空
        if (!entry.contract_id || entry.contract_id.trim() === "") {
            findings.push({
                contract_id: entry.contract_id || "",
                kind: entry.kind,
                severity: "hard_fail",
                rule: "contract_id_nonempty",
                message_zh: "contract_id 不能为空",
                evidence_refs: [],
            });
            continue;
        }
        if (idSet.has(entry.contract_id)) {
            findings.push({
                contract_id: entry.contract_id,
                kind: entry.kind,
                severity: "hard_fail",
                rule: "contract_id_unique",
                message_zh: `contract_id ${entry.contract_id} 重复`,
                evidence_refs: [],
            });
        }
        idSet.add(entry.contract_id);
        // 2. kind/state/owner/test 字段完整
        if (!entry.kind) {
            findings.push({
                contract_id: entry.contract_id,
                kind: entry.kind,
                severity: "hard_fail",
                rule: "kind_required",
                message_zh: `契约 ${entry.contract_id} 缺少 kind`,
                evidence_refs: [],
            });
        }
        if (!entry.state) {
            findings.push({
                contract_id: entry.contract_id,
                kind: entry.kind,
                severity: "hard_fail",
                rule: "state_required",
                message_zh: `契约 ${entry.contract_id} 缺少 state`,
                evidence_refs: [],
            });
        }
        if (!entry.owner_component) {
            findings.push({
                contract_id: entry.contract_id,
                kind: entry.kind,
                severity: "hard_fail",
                rule: "owner_required",
                message_zh: `契约 ${entry.contract_id} 缺少 owner_component`,
                evidence_refs: [],
            });
        }
        if (entry.test_files.length === 0) {
            findings.push({
                contract_id: entry.contract_id,
                kind: entry.kind,
                severity: "hard_fail",
                rule: "test_files_required",
                message_zh: `契约 ${entry.contract_id} 无测试文件，所有核心契约必须有测试`,
                evidence_refs: [],
            });
        }
        // 3. owner_files/test_files 存在性（当 existingFiles 提供时）
        if (existingFiles) {
            const isEnforcedOrHardFail = entry.state === "enforced" || entry.hard_fail_allowed;
            for (const f of entry.owner_files) {
                if (!existingFiles.has(f)) {
                    findings.push({
                        contract_id: entry.contract_id,
                        kind: entry.kind,
                        severity: isEnforcedOrHardFail ? "hard_fail" : "warning",
                        rule: "owner_file_exists",
                        message_zh: `契约 ${entry.contract_id} 的 owner_file ${f} 不存在${isEnforcedOrHardFail ? "（enforced/hard_fail 契约必须存在）" : ""}`,
                        evidence_refs: [f],
                    });
                }
            }
            for (const f of entry.test_files) {
                if (!existingFiles.has(f)) {
                    findings.push({
                        contract_id: entry.contract_id,
                        kind: entry.kind,
                        severity: isEnforcedOrHardFail ? "hard_fail" : "warning",
                        rule: "test_file_exists",
                        message_zh: `契约 ${entry.contract_id} 的 test_file ${f} 不存在${isEnforcedOrHardFail ? "（enforced/hard_fail 契约必须存在）" : ""}`,
                        evidence_refs: [f],
                    });
                }
            }
            for (const f of entry.lifecycle_test_files) {
                if (!existingFiles.has(f)) {
                    findings.push({
                        contract_id: entry.contract_id,
                        kind: entry.kind,
                        severity: "hard_fail",
                        rule: "lifecycle_test_file_exists",
                        message_zh: `契约 ${entry.contract_id} 的 lifecycle_test_file ${f} 不存在`,
                        evidence_refs: [f],
                    });
                }
            }
        }
        // 4. hard_fail_allowed=true 必须 state=enforced 且 lifecycle_test_files 非空
        if (entry.hard_fail_allowed) {
            if (entry.state !== "enforced") {
                findings.push({
                    contract_id: entry.contract_id,
                    kind: entry.kind,
                    severity: "hard_fail",
                    rule: "hard_fail_requires_enforced",
                    message_zh: `契约 ${entry.contract_id} 的 hard_fail_allowed=true 但 state=${entry.state}，只有 enforced 契约允许 hard fail`,
                    evidence_refs: [],
                });
            }
            if (entry.lifecycle_test_files.length === 0) {
                findings.push({
                    contract_id: entry.contract_id,
                    kind: entry.kind,
                    severity: "hard_fail",
                    rule: "hard_fail_requires_lifecycle_tests",
                    message_zh: `契约 ${entry.contract_id} 的 hard_fail_allowed=true 但无 lifecycle_test_files`,
                    evidence_refs: [],
                });
            }
        }
        // 5. advisory/experimental/draft 不得 hard_fail_allowed
        if ((entry.state === "advisory" ||
            entry.state === "experimental" ||
            entry.state === "draft") &&
            entry.hard_fail_allowed) {
            findings.push({
                contract_id: entry.contract_id,
                kind: entry.kind,
                severity: "hard_fail",
                rule: "non_enforced_no_hard_fail",
                message_zh: `契约 ${entry.contract_id} 的 state=${entry.state}，advisory/experimental/draft 契约不得 hard_fail_allowed=true`,
                evidence_refs: [],
            });
        }
        // 6. deprecated 必须有 replacement_contract_id 或 migration_note
        if (entry.state === "deprecated") {
            if (!entry.replacement_contract_id && !entry.migration_note) {
                findings.push({
                    contract_id: entry.contract_id,
                    kind: entry.kind,
                    severity: "hard_fail",
                    rule: "deprecated_requires_replacement",
                    message_zh: `契约 ${entry.contract_id} 已废弃但无 replacement_contract_id 或 migration_note`,
                    evidence_refs: [],
                });
            }
        }
        // 7. removed 不得被 workflow/prompt/consumed_by 主链路引用
        if (entry.state === "removed") {
            if (entry.consumed_by.length > 0) {
                findings.push({
                    contract_id: entry.contract_id,
                    kind: entry.kind,
                    severity: "hard_fail",
                    rule: "removed_not_referenced",
                    message_zh: `已移除契约 ${entry.contract_id} 仍被 consumed_by 引用: ${entry.consumed_by.join(", ")}`,
                    evidence_refs: entry.consumed_by,
                });
            }
            if (entry.prompt_refs.length > 0) {
                findings.push({
                    contract_id: entry.contract_id,
                    kind: entry.kind,
                    severity: "hard_fail",
                    rule: "removed_no_prompt_refs",
                    message_zh: `已移除契约 ${entry.contract_id} 仍被 prompt 引用: ${entry.prompt_refs.join(", ")}`,
                    evidence_refs: entry.prompt_refs,
                });
            }
        }
        // 8. depends_on 指向的契约必须存在
        for (const depId of entry.depends_on) {
            if (!getRegistry().has(depId)) {
                findings.push({
                    contract_id: entry.contract_id,
                    kind: entry.kind,
                    severity: "hard_fail",
                    rule: "dependency_exists",
                    message_zh: `契约 ${entry.contract_id} 依赖不存在的契约 ${depId}`,
                    evidence_refs: [depId],
                });
            }
            else {
                const dep = getRegistry().get(depId);
                // 8a. 依赖不得指向 removed
                if (dep.state === "removed") {
                    findings.push({
                        contract_id: entry.contract_id,
                        kind: entry.kind,
                        severity: "hard_fail",
                        rule: "dependency_not_removed",
                        message_zh: `契约 ${entry.contract_id} 依赖已移除的契约 ${depId}`,
                        evidence_refs: [depId],
                    });
                }
                // 8b. 指向 deprecated 必须有 migration note 或 replacement
                if (dep.state === "deprecated" && !dep.replacement_contract_id && !dep.migration_note) {
                    findings.push({
                        contract_id: entry.contract_id,
                        kind: entry.kind,
                        severity: "warning",
                        rule: "dependency_deprecated_migration",
                        message_zh: `契约 ${entry.contract_id} 依赖已废弃的契约 ${depId}，该废弃契约无替代或迁移说明`,
                        evidence_refs: [depId],
                    });
                }
            }
        }
        // 9. capability state 与 contract state 冲突检查
        if (entry.policy_id && entry.capability_ids && entry.capability_ids.length > 0) {
            for (const capId of entry.capability_ids) {
                const cap = getCapability(capId);
                if (cap) {
                    const conflict = checkCapabilityContractConflict(cap.state, entry.state, capId, entry.contract_id);
                    if (conflict) {
                        findings.push(conflict);
                    }
                }
            }
        }
    }
    return findings;
}
/**
 * 检查 capability state 与 contract state 冲突。
 * capability enforced 但对应 contract advisory/removed 必须报告。
 */
function checkCapabilityContractConflict(capState, contractState, capId, contractId) {
    // capability enforced 但 contract advisory/removed/draft — 冲突
    if (capState === "enforced" &&
        (contractState === "advisory" ||
            contractState === "removed" ||
            contractState === "draft")) {
        return {
            contract_id: contractId,
            kind: "capability",
            severity: "hard_fail",
            rule: "capability_contract_state_conflict",
            message_zh: `能力 ${capId} 状态为 enforced，但对应契约 ${contractId} 状态为 ${contractState}，存在冲突`,
            evidence_refs: [capId, contractId],
        };
    }
    // capability advisory 但 contract enforced — 冲突（反向）
    if (capState === "advisory" && contractState === "enforced") {
        return {
            contract_id: contractId,
            kind: "capability",
            severity: "warning",
            rule: "capability_contract_state_conflict",
            message_zh: `能力 ${capId} 状态为 advisory，但对应契约 ${contractId} 状态为 enforced，可能需要同步`,
            evidence_refs: [capId, contractId],
        };
    }
    return null;
}
/**
 * 验证 workflow 引用的契约是否合法。
 * workflow 引用不存在、removed 或非法 deprecated contract 必须 blocked。
 */
export function validateWorkflowContractRefs(workflowId, referencedContractIds) {
    const findings = [];
    for (const refId of referencedContractIds) {
        const entry = getRegistry().get(refId);
        if (!entry) {
            findings.push({
                contract_id: refId,
                kind: "workflow",
                severity: "hard_fail",
                rule: "workflow_ref_exists",
                message_zh: `工作流 ${workflowId} 引用不存在的契约 ${refId}`,
                evidence_refs: [workflowId, refId],
            });
            continue;
        }
        if (entry.state === "removed") {
            findings.push({
                contract_id: refId,
                kind: entry.kind,
                severity: "hard_fail",
                rule: "workflow_ref_not_removed",
                message_zh: `工作流 ${workflowId} 引用已移除的契约 ${refId}`,
                evidence_refs: [workflowId, refId],
            });
        }
        // deprecated 一律 hard_fail/blocked；有 replacement 提示迁移
        if (entry.state === "deprecated") {
            const hint = entry.replacement_contract_id
                ? `，替代契约: ${entry.replacement_contract_id}`
                : entry.migration_note
                    ? `，迁移说明: ${entry.migration_note}`
                    : "，无替代或迁移说明";
            findings.push({
                contract_id: refId,
                kind: entry.kind,
                severity: "hard_fail",
                rule: "workflow_ref_deprecated_blocked",
                message_zh: `工作流 ${workflowId} 引用已废弃的契约 ${refId}${hint}`,
                evidence_refs: [workflowId, refId],
            });
        }
        // advisory/experimental 只能 warning，不能阻断
        if (entry.state === "advisory" || entry.state === "experimental" || entry.state === "draft") {
            findings.push({
                contract_id: refId,
                kind: entry.kind,
                severity: "advisory",
                rule: "workflow_ref_advisory_only",
                message_zh: `工作流 ${workflowId} 引用的契约 ${refId} 状态为 ${entry.state}，只能 advisory，不能阻断主流程`,
                evidence_refs: [workflowId, refId],
            });
        }
    }
    return findings;
}
//# sourceMappingURL=validation.js.map