/**
 * 问题五十三: Workflow Template Pack — 工作流模板包契约。
 *
 * 强制执行:
 * - workflow template pack 不得只新增文件，必须 indexed → registered → injected → consumed → verified
 * - verified 状态必须有真实链路证据，禁止手工置绿
 * - 链路验证: 文件存在、ConsumableAssetRegistry 登记、workflow contract 引用、scenario 可达
 */
import { findConsumableAssetByPath } from "../templates/consumable_asset_registry.js";
import { listWorkflowContracts } from "../workflow/workflow_contract_registry.js";
import { EXTENSION_SCENARIOS } from "./extension_scenario_definitions.js";
import fs from "node:fs";
/** 模板消费必须按此顺序推进 */
const CONSUMPTION_PIPELINE = [
    "missing", "file_created", "indexed", "registered",
    "injected", "consumed", "verified",
];
/**
 * 创建工作流模板包契约。
 */
export function createWorkflowTemplatePackContract(overrides) {
    return {
        pack_id: "default-pack",
        workflows: [],
        mechanism_consumption_map: [],
        adapter_injection_points: [],
        registry_entries: [],
        scenario_coverage: [],
        ...overrides,
    };
}
/**
 * 创建工作流模板条目。
 */
export function createWorkflowTemplateEntry(workflowId, templatePath) {
    return {
        workflow_id: workflowId,
        template_path: templatePath,
        owner_mechanism_ids: [],
        consumed_contracts: [],
        required_sections: [],
        hard_rules: [],
        acceptance_checks: [],
        applies_to: ["soloforge_self", "user_project"],
        project_context: ["existing_system", "new_system", "empty_project", "unknown"],
        not_applicable_conditions: [],
    };
}
/**
 * 创建模板消费证据。
 */
export function createTemplateConsumptionEvidence(templatePath) {
    return {
        template_path: templatePath,
        template_consumption_status: "missing",
        workflow_template_refs: [],
        adapter_prompt_refs: [],
        route_trigger_refs: [],
        sync_migration_refs: [],
        scenario_refs: [],
    };
}
/**
 * 推进模板消费状态。
 */
export function advanceTemplateConsumptionStatus(currentStatus) {
    const idx = CONSUMPTION_PIPELINE.indexOf(currentStatus);
    if (idx === -1) {
        return { allowed: false, next: currentStatus, reason: `未知状态: ${currentStatus}` };
    }
    if (idx === CONSUMPTION_PIPELINE.length - 1) {
        return { allowed: false, next: currentStatus, reason: "已达到最终状态 verified" };
    }
    const next = CONSUMPTION_PIPELINE[idx + 1];
    return { allowed: true, next, reason: `${currentStatus} → ${next}` };
}
/**
 * 检查 workflow contract 是否引用了指定 workflow_id 的模板。
 */
export function findWorkflowContractForTemplate(workflowId) {
    const contracts = listWorkflowContracts();
    // workflow_id 可能是 "architecture_design"，contract id 是 "wf-architecture-design"
    const match = contracts.find(c => c.id === workflowId ||
        c.id === `wf-${workflowId.replace(/_/g, "-")}` ||
        c.id.endsWith(workflowId.replace(/_/g, "-")));
    if (match) {
        return { found: true, prompt_template: match.prompt_template };
    }
    return { found: false, prompt_template: "" };
}
/**
 * 已注册的 scenario ID 集合（从 EXTENSION_SCENARIOS 提取）。
 */
function getRegisteredScenarioIds() {
    return EXTENSION_SCENARIOS.map(s => s.id);
}
/**
 * 验证模板消费证据链路的真实性。
 * 1. template_path 文件真实存在
 * 2. template_path 通过 ConsumableAssetRegistry path 查到对应 asset
 * 3. asset.owner_mechanism_id 与 workflow.owner_mechanism_ids 一致
 * 4. workflow contract 真实存在且 prompt_template 匹配
 * 5. workflow_template_refs 指向真实 contract
 * 6. sync_migration_refs 解析 manifest:<path> 并确认路径真实存在
 * 7. scenario_refs 必须指向真实 scenario ID
 */
export function validateEvidenceChain(workflow, evidence) {
    const chainViolations = [];
    // 1. template_path 文件真实存在
    if (!fs.existsSync(workflow.template_path)) {
        chainViolations.push(`模板路径 "${workflow.template_path}" 文件不存在`);
    }
    // 2. template_path 在 ConsumableAssetRegistry 中通过 path 查找
    const asset = findConsumableAssetByPath(workflow.template_path);
    if (!asset) {
        chainViolations.push(`模板路径 "${workflow.template_path}" 未在 ConsumableAssetRegistry 登记（path 查找无结果）`);
    }
    else {
        // 3. asset.owner_mechanism_id 与 workflow.owner_mechanism_ids 一致
        const ownerId = asset.owner_mechanism_id ?? "";
        const ownerMatch = workflow.owner_mechanism_ids.includes(ownerId);
        if (!ownerMatch) {
            chainViolations.push(`模板 "${workflow.template_path}" 的 asset.owner_mechanism_id "${ownerId}" 不在 workflow.owner_mechanism_ids [${workflow.owner_mechanism_ids.join(", ")}] 中`);
        }
    }
    // 4. workflow contract 引用检查
    const contractMatch = findWorkflowContractForTemplate(workflow.workflow_id);
    if (!contractMatch.found) {
        chainViolations.push(`模板 ${workflow.template_path} (workflow_id=${workflow.workflow_id}) 未在 WorkflowContractRegistry 找到对应契约`);
    }
    // 5. workflow_template_refs 指向真实 workflow contract
    if (evidence.workflow_template_refs.length > 0) {
        const contracts = listWorkflowContracts();
        for (const ref of evidence.workflow_template_refs) {
            const exists = contracts.some(c => c.id === ref || c.prompt_template === ref);
            if (!exists) {
                chainViolations.push(`workflow_template_ref "${ref}" 不指向任何已注册的 WorkflowContract`);
            }
        }
    }
    // 6. sync_migration_refs 必须解析 manifest:<path> 并确认路径存在
    if (evidence.sync_migration_refs.length > 0) {
        const registeredIds = getRegisteredScenarioIds();
        for (const ref of evidence.sync_migration_refs) {
            if (ref.startsWith("manifest:")) {
                const manifestPath = ref.slice("manifest:".length);
                if (!fs.existsSync(manifestPath)) {
                    chainViolations.push(`sync_migration_ref "${ref}" 解析路径 "${manifestPath}" 文件不存在`);
                }
            }
            else if (ref.startsWith("sha256:")) {
                // hash 格式，跳过文件检查
            }
            else if (ref.startsWith("scenario-ref:")) {
                // 场景引用格式
                const scenarioId = ref.slice("scenario-ref:".length);
                if (!registeredIds.includes(scenarioId)) {
                    chainViolations.push(`sync_migration_ref "${ref}" 引用的 scenario "${scenarioId}" 不在 EXTENSION_SCENARIOS 中`);
                }
            }
            else if (!ref.includes("/")) {
                chainViolations.push(`sync_migration_ref "${ref}" 格式不合法，应为 manifest:<path>、sha256:<hash> 或 scenario-ref:<id>`);
            }
            else if (!fs.existsSync(ref)) {
                chainViolations.push(`sync_migration_ref "${ref}" 路径文件不存在`);
            }
        }
    }
    // 7. scenario_refs 必须指向真实 scenario ID
    if (evidence.scenario_refs.length > 0) {
        const registeredIds = getRegisteredScenarioIds();
        for (const ref of evidence.scenario_refs) {
            if (!registeredIds.includes(ref)) {
                chainViolations.push(`scenario_ref "${ref}" 不在已注册的 scenario ID 中 [${registeredIds.join(", ")}]`);
            }
        }
    }
    return chainViolations;
}
/**
 * 验证模板包完整性。
 * - 不得只新增文件而不走完消费 pipeline
 * - 禁止手工置绿: verified 必须有真实链路证据
 * - 链路真实性验证: ConsumableAssetRegistry、WorkflowContract、scenario 格式
 */
export function validateWorkflowTemplatePack(pack, consumptionEvidences) {
    const violations = [];
    const pipelineProgress = [];
    for (const workflow of pack.workflows) {
        const evidence = consumptionEvidences.find(e => e.template_path === workflow.template_path);
        const status = evidence?.template_consumption_status ?? "missing";
        if (status !== "verified") {
            const nextRequired = advanceTemplateConsumptionStatus(status);
            if (nextRequired.allowed) {
                violations.push(`模板 ${workflow.template_path} 停在 ${status}，未走完消费 pipeline（下一步: ${nextRequired.next}）`);
            }
        }
        if (status === "verified" && evidence) {
            const hasWorkflowRef = evidence.workflow_template_refs && evidence.workflow_template_refs.length > 0;
            const hasRouteRef = evidence.route_trigger_refs && evidence.route_trigger_refs.length > 0;
            const hasSyncRef = evidence.sync_migration_refs && evidence.sync_migration_refs.length > 0;
            const hasScenarioRef = evidence.scenario_refs && evidence.scenario_refs.length > 0;
            if (!hasWorkflowRef && !hasRouteRef) {
                violations.push(`模板 ${workflow.template_path} 标记 verified 但缺少 workflow_template_refs 或 route_trigger_refs，疑似手工置绿`);
            }
            if (!hasSyncRef) {
                violations.push(`模板 ${workflow.template_path} 标记 verified 但缺少 sync_migration_refs，未证明 sync/migrate 可追踪`);
            }
            if (!hasScenarioRef) {
                violations.push(`模板 ${workflow.template_path} 标记 verified 但缺少 scenario_refs，未证明场景矩阵引用`);
            }
            // 链路真实性验证
            const chainViolations = validateEvidenceChain(workflow, evidence);
            violations.push(...chainViolations);
        }
        const hasMap = pack.mechanism_consumption_map.some(m => m.template_path === workflow.template_path);
        if (!hasMap) {
            violations.push(`模板 ${workflow.template_path} 缺少机制消费地图`);
        }
        const nextStep = advanceTemplateConsumptionStatus(status);
        pipelineProgress.push({
            template_path: workflow.template_path,
            current_status: status,
            next_required: nextStep.allowed ? nextStep.next : "done",
        });
    }
    return {
        valid: violations.length === 0,
        violations,
        pipeline_progress: pipelineProgress,
    };
}
/**
 * 验证机制消费地图。
 */
export function validateMechanismConsumptionMap(map, templatePaths) {
    const missing = [];
    for (const path of templatePaths) {
        const hasEntries = map.some(m => m.template_path === path);
        if (!hasEntries) {
            missing.push(`模板 ${path} 缺少机制消费条目`);
        }
    }
    return { valid: missing.length === 0, missing };
}
//# sourceMappingURL=workflow_template_pack.js.map