import { debug } from "../core/logger.js";
// ── 常量定义 ──
/** 输出产物基础目录 */
export const OUTPUT_BASE = ".soloforge/output";
/** 内部报告子目录 */
export const REPORTS_SUBDIR = "_reports";
const ARTIFACT_DEFAULTS = {
    prototype_spec: { defaultName: "原型说明", format: "markdown", overwritePolicy: "version" },
    requirement_analysis: { defaultName: "需求分析", format: "markdown", overwritePolicy: "version" },
    api_spec: { defaultName: "接口设计", format: "markdown", overwritePolicy: "version" },
    api_design: { defaultName: "接口设计", format: "markdown", overwritePolicy: "version" },
    design_doc: { defaultName: "设计文档", format: "markdown", overwritePolicy: "version" },
    detailed_design: { defaultName: "详细设计", format: "markdown", overwritePolicy: "version" },
    test_plan: { defaultName: "测试计划", format: "markdown", overwritePolicy: "version" },
    migration_plan: { defaultName: "迁移方案", format: "markdown", overwritePolicy: "version" },
    task_breakdown: { defaultName: "任务拆解", format: "markdown", overwritePolicy: "version" },
    task_plan: { defaultName: "任务计划", format: "markdown", overwritePolicy: "version" },
    root_cause: { defaultName: "根因分析", format: "markdown", overwritePolicy: "version" },
    incident_review: { defaultName: "故障复盘", format: "markdown", overwritePolicy: "version" },
    review_report: { defaultName: "审查报告", format: "markdown", overwritePolicy: "version" },
    verification_report: { defaultName: "验证报告", format: "markdown", overwritePolicy: "version" },
    acceptance_checklist: { defaultName: "验收清单", format: "markdown", overwritePolicy: "version" },
    interaction_spec: { defaultName: "交互规约", format: "markdown", overwritePolicy: "version" },
    domain_model: { defaultName: "领域模型", format: "markdown", overwritePolicy: "version" },
    tech_decision_record: { defaultName: "技术选型记录", format: "markdown", overwritePolicy: "version" },
    knowledge_rule: { defaultName: "知识规则", format: "markdown", overwritePolicy: "version" },
    custom: { defaultName: "自定义", format: "markdown", overwritePolicy: "confirm" },
};
/** 序号映射 */
const ARTIFACT_ORDER = {
    prototype_spec: 1,
    requirement_analysis: 2,
    api_spec: 3,
    api_design: 3,
    design_doc: 4,
    detailed_design: 4,
    test_plan: 5,
    migration_plan: 6,
    task_breakdown: 7,
    task_plan: 7,
    root_cause: 8,
    incident_review: 9,
    review_report: 10,
    verification_report: 11,
    acceptance_checklist: 12,
    interaction_spec: 13,
    domain_model: 14,
    tech_decision_record: 15,
    knowledge_rule: 16,
    custom: 99,
};
// ── 生命周期转换 ──
const VALID_TRANSITIONS = {
    draft: ["verified", "superseded", "archived"],
    verified: ["accepted", "superseded", "archived"],
    accepted: ["archived"],
    superseded: [],
    archived: [],
};
/** 判断产物状态是否允许从 from 转换到 to
 * @param from - 当前状态
 * @param to - 目标状态
 * @returns 是否允许转换
 */
export function canTransition(from, to) {
    return VALID_TRANSITIONS[from]?.includes(to) ?? false;
}
/** draft → verified 需要 verification */
export function transitionRequiresVerification(from, to) {
    return from === "draft" && to === "verified";
}
/** → accepted 需要用户或后续 workflow 确认 */
export function transitionRequiresAcceptance(_from, to) {
    return to === "accepted";
}
// ── 路径生成 ──
/** 默认输出路径: .soloforge/output/{task_id}/{NN}-{kind-name}.md */
export function getDefaultArtifactPath(kind, taskId) {
    const num = String(ARTIFACT_ORDER[kind]).padStart(2, "0");
    const name = ARTIFACT_DEFAULTS[kind].defaultName;
    return `${OUTPUT_BASE}/${taskId}/${num}-${name}.md`;
}
/** 内部报告路径: .soloforge/output/{task_id}/_reports/{name}.md */
export function getReportPath(taskId, reportName) {
    return `${OUTPUT_BASE}/${taskId}/${REPORTS_SUBDIR}/${reportName}.md`;
}
/** 版本化路径: 同名产物 .v2.md */
export function versionPath(path, version) {
    const base = path.replace(/\.md$/, "");
    return version > 1 ? `${base}.v${version}.md` : path;
}
// ── 禁止写入目标 ──
const FORBIDDEN_WRITE_PATHS = [
    { pattern: /^\.soloforge\/knowledge\//, reason: "知识库写入必须走知识演进" },
    { pattern: /^\.soloforge\/config\./, reason: "配置文件写入需确认" },
    { pattern: /^README\.md$/i, reason: "正式文档写入需用户确认" },
    { pattern: /^docs\//, reason: "正式 docs 目录写入需用户确认" },
];
/** 检查路径是否禁止写入
 * @param path - 待检查的文件路径
 * @returns 禁止结果及原因
 */
export function isWriteForbidden(path) {
    for (const { pattern, reason } of FORBIDDEN_WRITE_PATHS) {
        if (pattern.test(path))
            return { forbidden: true, reason };
    }
    return { forbidden: false };
}
/** 外部 input material 路径禁止写回 */
export function isInputMaterialPath(path, inputMaterialPaths) {
    return inputMaterialPaths.includes(path);
}
// ── 工厂函数 ──
let artifactCounter = 0;
/** 创建输出产物实例
 * @param params - 产物创建参数
 * @param params.kind - 产物类型
 * @param params.task_id - 任务 ID
 * @param params.workflow_id - 工作流 ID
 * @param params.created_by - 创建者
 * @param params.path - 输出路径（可选）
 * @param params.format - 产物格式（可选）
 * @param params.source_material_refs - 源材料引用列表（可选）
 * @param params.knowledge_refs - 知识引用列表（可选）
 * @param params.evidence_refs - 证据引用列表（可选）
 * @param params.hash - 产物哈希（可选）
 * @returns 输出产物实例
 */
/**
 * 创建输出产物实例。
 * @param kind - 产物类型
 * @param taskId - 任务 ID
 * @returns 新建的产物实例
 */
export function createOutputArtifact(params) {
    debug("产物契约", "createOutputArtifact() 创建产物, kind=%s, task_id=%s", params.kind, params.task_id);
    const defaults = ARTIFACT_DEFAULTS[params.kind];
    const artifactId = `artifact-${Date.now()}-${++artifactCounter}`;
    const defaultPath = getDefaultArtifactPath(params.kind, params.task_id);
    return {
        artifact_id: artifactId,
        kind: params.kind,
        path: params.path ?? defaultPath,
        format: params.format ?? defaults.format,
        created_by: params.created_by,
        workflow_id: params.workflow_id,
        task_id: params.task_id,
        source_material_refs: params.source_material_refs ?? [],
        knowledge_refs: params.knowledge_refs ?? [],
        evidence_refs: params.evidence_refs ?? [],
        status: "draft",
        overwrite_policy: defaults.overwritePolicy,
        hash: params.hash,
        created_at: new Date().toISOString(),
        version: 1,
    };
}
// ── 查询函数 ──
/** 获取指定产物类型的默认配置
 * @param kind - 产物类型
 * @returns 默认配置（默认名称、格式、覆盖策略）
 */
export function getArtifactDefaults(kind) {
    return ARTIFACT_DEFAULTS[kind];
}
/** 列出所有支持的产物类型
 * @returns 产物类型数组
 */
export function listArtifactKinds() {
    return Object.keys(ARTIFACT_DEFAULTS);
}
/** 获取指定产物类型的验收检查项
 * @param kind - 产物类型
 * @param artifact - 待检查的产物
 * @returns 验收检查项列表
 */
export function getAcceptanceChecks(kind, artifact) {
    debug("产物契约", "getAcceptanceChecks() 执行验收检查, kind=%s, artifact=%s", kind, artifact.artifact_id);
    const checks = [];
    // 通用检查: 有 artifact_id (hard_fail)
    checks.push({
        id: "AC-ART-01",
        description: "产物有唯一 artifact_id",
        passed: !!artifact.artifact_id,
        severity: "hard_fail",
    });
    // 通用检查: 路径包含 task_id (hard_fail)
    checks.push({
        id: "AC-ART-02",
        description: "默认输出路径包含 task_id",
        passed: artifact.path.includes(artifact.task_id),
        severity: "hard_fail",
    });
    // 通用检查: 不在源码目录 (hard_fail)
    checks.push({
        id: "AC-ART-03",
        description: "产物不在项目源码目录",
        passed: !artifact.path.startsWith("src/"),
        severity: "hard_fail",
    });
    // prototype_spec: 严格检查
    if (kind === "prototype_spec") {
        // 模板: 必须有 knowledge_refs 引用模板，或 evidence_refs 中有模板证据
        const hasTemplateRef = artifact.knowledge_refs.length > 0
            || artifact.evidence_refs.some(r => r.includes("template"));
        checks.push({
            id: "AC-PS-01",
            description: "使用指定模板 (knowledge_refs 或 template evidence)",
            passed: hasTemplateRef,
            severity: "hard_fail",
            note: "prototype_spec 必须引用模板知识或 template evidence",
        });
        // source_material_refs 必须非空
        checks.push({
            id: "AC-PS-02",
            description: "引用源码包 source_material_refs 非空",
            passed: artifact.source_material_refs.length > 0,
            severity: "hard_fail",
        });
        // ingestion evidence_refs 必须非空
        checks.push({
            id: "AC-PS-03",
            description: "引用源码包 ingestion evidence_refs 非空",
            passed: artifact.evidence_refs.some(r => r.startsWith("ingestion:")),
            severity: "hard_fail",
        });
        // 产物必须有 hash 或 file/hash evidence (hard_fail)
        const hasFileEvidence = !!artifact.hash
            || artifact.evidence_refs.some(r => r.includes("file:") || r.includes("hash:"));
        checks.push({
            id: "AC-PS-04",
            description: "产物必须有 hash 或 file/hash evidence",
            passed: hasFileEvidence,
            severity: "hard_fail",
        });
        // 人工确认规则
        checks.push({
            id: "AC-PS-05",
            description: "Manual Confirm: 产物内容需人工确认",
            passed: false,
            severity: "advisory",
            note: "prototype_spec 产物内容需人工确认准确性",
        });
    }
    if (kind === "api_design") {
        checks.push({
            id: "AC-API-01",
            description: "引用需求/原型 evidence",
            passed: artifact.evidence_refs.length > 0 || artifact.source_material_refs.length > 0,
        });
    }
    return checks;
}
/** 执行验收检查并生成 ArtifactVerificationResult */
export function verifyArtifact(kind, artifact) {
    debug("产物契约", "验证产物 %s (%s)", artifact.artifact_id, kind);
    const checks = getAcceptanceChecks(kind, artifact);
    // 所有非 advisory 检查必须通过 (hard_fail 和无 severity 的检查)
    const blockingChecks = checks.filter(c => c.severity !== "advisory");
    const blockingPassed = blockingChecks.every(c => c.passed);
    const failedChecks = checks.filter(c => !c.passed);
    const summary = blockingPassed
        ? `All checks passed (${checks.length}/${checks.length})`
        : `Failed: ${failedChecks.map(c => c.id).join(", ")} (${failedChecks.length}/${checks.length})`;
    return { passed: blockingPassed, checks, summary };
}
// ── 治理校验 ──
/** 执行产物治理校验
 * @param artifacts - 待校验的产物列表
 * @returns 治理发现列表
 */
export function validateArtifactContracts(artifacts) {
    debug("产物契约", "开始治理校验，共 %d 个产物", artifacts.length);
    const findings = [];
    for (const a of artifacts) {
        // 规则 1: 默认输出路径必须含 task_id
        if (a.path.startsWith(OUTPUT_BASE) && !a.path.includes(a.task_id)) {
            findings.push({
                severity: "hard_fail",
                artifact_id: a.artifact_id,
                rule: "gc-artifact-no-task-id",
                message: `产物 ${a.artifact_id} 的默认输出路径不包含 task_id`,
            });
        }
        // 规则 2: 默认覆盖策略必须是 version 或 never
        if (a.overwrite_policy === "allowed" && a.path.startsWith(OUTPUT_BASE)) {
            findings.push({
                severity: "hard_fail",
                artifact_id: a.artifact_id,
                rule: "gc-artifact-unsafe-overwrite",
                message: `产物 ${a.artifact_id} 在默认路径使用 allowed 覆盖策略`,
            });
        }
        // 规则 3: accepted 必须有 verification evidence
        if (a.status === "accepted") {
            const hasVerificationEvidence = a.evidence_refs.some(r => r.includes("verification"));
            const hasAcceptanceEvidence = a.evidence_refs.some(r => r.includes("acceptance") || r.includes("workflow_adoption"));
            if (!hasVerificationEvidence) {
                findings.push({
                    severity: "hard_fail",
                    artifact_id: a.artifact_id,
                    rule: "gc-artifact-no-verification-evidence",
                    message: `产物 ${a.artifact_id} 状态为 accepted 但缺少 verification evidence`,
                });
            }
            if (!hasAcceptanceEvidence) {
                findings.push({
                    severity: "hard_fail",
                    artifact_id: a.artifact_id,
                    rule: "gc-artifact-no-acceptance-evidence",
                    message: `产物 ${a.artifact_id} 状态为 accepted 但缺少 acceptance/workflow_adoption evidence`,
                });
            }
        }
        // 规则 4: 产物不得在源码目录
        if (a.path.startsWith("src/")) {
            findings.push({
                severity: "hard_fail",
                artifact_id: a.artifact_id,
                rule: "gc-artifact-in-src",
                message: `产物 ${a.artifact_id} 写入源码目录: ${a.path}`,
            });
        }
        // 规则 5: 外部 input material 路径禁止写回
        if (a.source_material_refs.some((r) => a.path === r)) {
            findings.push({
                severity: "hard_fail",
                artifact_id: a.artifact_id,
                rule: "gc-artifact-write-back-input",
                message: `产物 ${a.artifact_id} 写回 input material 路径: ${a.path}`,
            });
        }
        // 规则 6: 知识库路径禁止直接写入
        if (a.path.startsWith(".soloforge/knowledge/")) {
            findings.push({
                severity: "hard_fail",
                artifact_id: a.artifact_id,
                rule: "gc-artifact-write-knowledge",
                message: `产物 ${a.artifact_id} 直接写入知识库: ${a.path}`,
            });
        }
        // 规则 7: status 合法性
        const validStatuses = ["draft", "verified", "accepted", "superseded", "archived"];
        if (!validStatuses.includes(a.status)) {
            findings.push({
                severity: "hard_fail",
                artifact_id: a.artifact_id,
                rule: "gc-artifact-invalid-status",
                message: `产物 ${a.artifact_id} 状态无效: ${a.status}`,
            });
        }
        // 规则 8: kind 合法性
        if (!ARTIFACT_DEFAULTS[a.kind]) {
            findings.push({
                severity: "hard_fail",
                artifact_id: a.artifact_id,
                rule: "gc-artifact-invalid-kind",
                message: `产物 ${a.artifact_id} 类型无效: ${a.kind}`,
            });
        }
        // 规则 9: 版本号
        if (a.version !== undefined && a.version < 1) {
            findings.push({
                severity: "hard_fail",
                artifact_id: a.artifact_id,
                rule: "gc-artifact-invalid-version",
                message: `产物 ${a.artifact_id} 版本号无效: ${a.version}`,
            });
        }
        // 规则 10: 正式 docs 写入需确认
        const writeCheck = isWriteForbidden(a.path);
        if (writeCheck.forbidden) {
            findings.push({
                severity: "advisory",
                artifact_id: a.artifact_id,
                rule: "gc-artifact-formal-docs",
                message: `产物 ${a.artifact_id} 写入正式路径需确认: ${writeCheck.reason}`,
            });
        }
    }
    if (findings.length > 0) {
        const hardFails = findings.filter(f => f.severity === "hard_fail");
        if (hardFails.length > 0) {
            debug("产物契约", "治理校验发现 %d 个 hard_fail", hardFails.length);
        }
    }
    return findings;
}
/** 验证状态转换合法性 */
export function validateTransition(artifact, newStatus, hasVerification, hasAcceptance) {
    debug("产物契约", "validateTransition() 验证状态转换, artifact=%s, %s -> %s", artifact.artifact_id, artifact.status, newStatus);
    const findings = [];
    if (!canTransition(artifact.status, newStatus)) {
        findings.push({
            severity: "hard_fail",
            artifact_id: artifact.artifact_id,
            rule: "gc-artifact-invalid-transition",
            message: `产物 ${artifact.artifact_id} 不允许 ${artifact.status} → ${newStatus}`,
        });
    }
    if (transitionRequiresVerification(artifact.status, newStatus) && !hasVerification) {
        findings.push({
            severity: "hard_fail",
            artifact_id: artifact.artifact_id,
            rule: "gc-artifact-no-verification",
            message: `产物 ${artifact.artifact_id} 从 ${artifact.status} → verified 需要 artifact verification`,
        });
    }
    if (transitionRequiresAcceptance(artifact.status, newStatus) && !hasAcceptance) {
        findings.push({
            severity: "hard_fail",
            artifact_id: artifact.artifact_id,
            rule: "gc-artifact-no-acceptance",
            message: `产物 ${artifact.artifact_id} → accepted 需要用户确认或后续 workflow 引用`,
        });
    }
    return findings;
}
//# sourceMappingURL=artifact_contract_registry.js.map