/**
 * intent_expander — 知识解析与注入边界门控。
 *
 * 从主 expand() 函数提取: 生命周期知识评估、
 * 项目知识门控、知识索引查询、注入边界
 * 强制执行和消费轨迹记录。
 */
import fss from "node:fs";
import { debugLog } from "../../core/logger.js";
import { evaluateLifecycleKnowledgeDecision } from "../../contracts/lifecycle_knowledge_contract.js";
import { enforceKnowledgeInjectionBoundary, validateInjectionReport, getInjectedEntryIds } from "../../knowledge/knowledge_injection_boundary.js";
import { extractTraceabilityIds } from "../../contracts/traceability.js";
import { listMechanismLayerMaps } from "../../contracts/dual_layer_mechanism_registry.js";
import { mergeKnowledgeEntries, getAffectedRepos, inferScopeFromIntentAndConfig, buildBlockedResult, } from "./helpers.js";
import { queryKnowledgeForRoute, projectKnowledgeAssetToEntry, } from "./knowledge.js";
// ── 知识解析 ──
export async function resolveKnowledge(projectPath, intent, classification, config, knowledgeIndex, routeDecision, skipProjectKnowledgeHardBlock, safeIntent, safeGoal, workflowContract, inputMaterials, ingestionEvidences, promptInjectionPlan, outputArtifactRecord, workflowGovernanceFindings, taskStage) {
    const affectedRepos = getAffectedRepos(classification);
    const scopeFilters = affectedRepos.length > 0
        ? affectedRepos
        : inferScopeFromIntentAndConfig(intent, classification, config);
    const knowledgeLimit = classification.strategy === "quick_fix" ? 3 : 15;
    // TaskStage → lifecycle_stage 映射（替代粗略的 route 近似）
    const TASK_STAGE_TO_LIFECYCLE = {
        "需求分析": "requirements_intake",
        "现有系统分析": "requirements_intake",
        "架构设计": "architecture_design",
        "详细设计": "detail_design",
        "任务规划": "slice_planning",
        "编码与单元测试": "implementation",
        "代码审查": "implementation",
        "联调验证": "testing",
    };
    const lifecycleKnowledgeDecision = evaluateLifecycleKnowledgeDecision({
        projectPath,
        consumer: "sf_expand",
        intent,
        route: routeDecision?.route,
        tech_stack: [
            config.tech_stack?.backend?.lang,
            config.tech_stack?.backend?.framework,
            config.tech_stack?.frontend?.lang,
            config.tech_stack?.frontend?.framework,
        ].filter(Boolean),
        lifecycle_stage: taskStage ? TASK_STAGE_TO_LIFECYCLE[taskStage] : undefined,
        traceability_ids: [
            ...extractTraceabilityIds(intent),
            ...(classification.traceability_ids ?? []),
        ],
        config,
        selection_limit: 6,
        record_trace: true,
    });
    const projectKnowledgeReport = lifecycleKnowledgeDecision.project_knowledge;
    const projectKnowledgeFindings = projectKnowledgeReport.assets.flatMap((asset) => asset.findings.map((finding) => ({
        rel_path: asset.rel_path,
        code: finding.code,
        severity: finding.severity,
        message_zh: finding.message_zh,
    })));
    if (!skipProjectKnowledgeHardBlock && projectKnowledgeReport.hard_fail_count > 0) {
        const lines = projectKnowledgeFindings
            .filter((finding) => finding.severity === "hard_fail")
            .map((finding) => `- [${finding.code}] ${finding.rel_path}: ${finding.message_zh}`);
        return {
            projectKnowledgeReport,
            projectKnowledgeFindings,
            projectKnowledgeSelection: lifecycleKnowledgeDecision.knowledge_selection,
            selectedProjectKnowledge: [],
            projectKnowledgeEntries: [],
            matchedEntries: [],
            filteredEntries: [],
            injectionReport: { indexed: [], injectable: [], injected_required: [], injected_supporting: [], advisory_only: [], excluded: [], missing_required_knowledge: [], conflicts: [], budget: { requested: 0, injected: 0, advisory: 0, dropped: 0 }, generated_at: "" },
            degraded: true,
            governanceFindings: [],
            blockedResult: buildBlockedResult([
                "## 阻塞：用户项目知识规则不可消费",
                "",
                `任务: ${safeIntent}`,
                "",
                "项目 .soloforge/knowledge 中存在 hard rule 身份、路由或触发条件问题。",
                "这些规则如果继续放行，会让 AI 在真实任务中无法稳定知道该遵守哪些项目规则。",
                "",
                ...lines,
                "",
                "请修复以上项目规则后重新调用。",
            ].join("\n"), safeGoal, {
                constraints: ["用户项目知识规则不可消费"],
                stopConditions: ["修复 .soloforge/knowledge hard rule 路由或身份冲突"],
                projectKnowledge: {
                    total: projectKnowledgeReport.total,
                    hard_fail_count: projectKnowledgeReport.hard_fail_count,
                    warning_count: projectKnowledgeReport.warning_count,
                    selected: [],
                    findings: projectKnowledgeFindings,
                },
                workflowTrace: workflowContract ? {
                    workflow_id: workflowContract.id, route: routeDecision?.route ?? "",
                    execution_shape: routeDecision?.execution_shape ?? "",
                    mutation_allowed: workflowContract.mutation_allowed,
                    required_mechanisms: workflowContract.required_mechanisms,
                    governance_findings: projectKnowledgeFindings
                        .filter((finding) => finding.severity === "hard_fail")
                        .map((finding) => ({ severity: "hard_fail", rule: finding.code, message: `${finding.rel_path}: ${finding.message_zh}` })),
                    degraded: true, state_transition_target: "manual_required",
                } : undefined,
            }),
        };
    }
    const projectKnowledgeSelection = lifecycleKnowledgeDecision.knowledge_selection;
    const selectedProjectKnowledge = projectKnowledgeSelection.selected.map((decision) => decision.asset);
    const projectKnowledgeEntries = selectedProjectKnowledge.map(projectKnowledgeAssetToEntry).filter(Boolean);
    const matchedEntries = mergeKnowledgeEntries([
        ...queryKnowledgeForRoute(knowledgeIndex, intent, scopeFilters, config, routeDecision, knowledgeLimit, taskStage),
        ...projectKnowledgeEntries,
    ]);
    // 知识注入边界
    const productFilters = [config.product_profile];
    const injectionReport = enforceKnowledgeInjectionBoundary(matchedEntries, routeDecision, scopeFilters, undefined, knowledgeLimit, productFilters, undefined, 12000, taskStage);
    const injectedIds = new Set(getInjectedEntryIds(injectionReport));
    const filteredEntries = matchedEntries.filter((e) => injectedIds.has(e.id));
    if (filteredEntries.length > 0) {
        knowledgeIndex.markUsed(filteredEntries.map((e) => e.id));
    }
    // 记录消费轨迹
    const { recordConsumptionTrace, CONSUMER_FIELD_CONTRACTS } = await import("../../templates/consumption_trace_store.js");
    const { listConsumableAssetsByConsumer } = await import("../../templates/consumable_asset_registry.js");
    const expanderRegistryAssets = listConsumableAssetsByConsumer("intent_expander")
        .filter((a) => a.consumption_mode === "required");
    for (const asset of expanderRegistryAssets) {
        const artifactMatch = asset.trigger?.match(/^output_artifact\.kind=(.+)$/);
        if (artifactMatch) {
            if (routeDecision?.output_artifact?.kind !== artifactMatch[1])
                continue;
        }
        const { getContractByPath } = await import("../../templates/template_asset_contract_registry.js");
        const contract = getContractByPath(asset.path);
        recordConsumptionTrace({
            consumer: "expander",
            asset_id: asset.id,
            asset_path: asset.path,
            fields_consumed: CONSUMER_FIELD_CONTRACTS.expander,
            matched_reason: `route=${routeDecision?.route ?? "unknown"} shape=${routeDecision?.execution_shape ?? "unknown"} trigger=${asset.trigger ?? "none"}`,
            task_id_or_route: routeDecision?.route ?? "expand",
            consumed_at: new Date().toISOString(),
            declared_consumer: contract?.mainline_consumer,
        });
    }
    if (filteredEntries.length > 0 && routeDecision) {
        for (const entry of filteredEntries.slice(0, 5)) {
            recordConsumptionTrace({
                consumer: "expander",
                asset_id: entry.id,
                fields_consumed: CONSUMER_FIELD_CONTRACTS.expander,
                matched_reason: `route=${routeDecision.route} shape=${routeDecision.execution_shape} injected`,
                task_id_or_route: routeDecision.route,
                consumed_at: new Date().toISOString(),
            });
        }
    }
    // 治理校验
    const governanceFindings = validateInjectionReport(injectionReport);
    const hardFails = governanceFindings.filter((f) => f.severity === "hard_fail");
    injectionReport.governance_findings = governanceFindings;
    const degraded = filteredEntries.length === 0
        && injectionReport.injected_required.length === 0;
    if (hardFails.length > 0) {
        debugLog("意图膨胀: 注入校验失败，%d 个 hard_fail", hardFails.length);
        const failMessages = hardFails.map((f) => f.message).join("\n");
        const hasMissingRequiredKnowledge = injectionReport.missing_required_knowledge && injectionReport.missing_required_knowledge.length > 0;
        const missingDesc = hasMissingRequiredKnowledge
            ? (injectionReport.missing_required_knowledge ?? []).map((m) => m.reason).join("\n")
            : "";
        const missingSection = missingDesc ? `\n\n缺少的必需知识:\n${missingDesc}` : "";
        return {
            projectKnowledgeReport,
            projectKnowledgeFindings,
            projectKnowledgeSelection,
            selectedProjectKnowledge,
            projectKnowledgeEntries,
            matchedEntries,
            filteredEntries,
            injectionReport,
            degraded,
            governanceFindings,
            blockedResult: buildBlockedResult(`## 阻塞：注入校验失败\n\n任务: ${safeIntent}\n\n以下硬性校验未通过:\n${failMessages}${missingSection}\n\n请修正后重新调用。`, safeGoal, {
                constraints: ["注入校验失败，等待修正"], stopConditions: ["注入校验失败"],
                injectionReport: injectionReport,
                inputMaterials: inputMaterials, ingestionEvidences: ingestionEvidences,
                promptInjectionPlan: promptInjectionPlan, outputArtifactRecord: outputArtifactRecord,
                workflowTrace: workflowContract ? {
                    workflow_id: workflowContract.id, route: routeDecision?.route ?? "",
                    execution_shape: routeDecision?.execution_shape ?? "",
                    mutation_allowed: workflowContract.mutation_allowed,
                    required_mechanisms: workflowContract.required_mechanisms,
                    governance_findings: workflowGovernanceFindings,
                    degraded: true, state_transition_target: "none",
                } : undefined,
            }),
        };
    }
    return {
        projectKnowledgeReport,
        projectKnowledgeFindings,
        projectKnowledgeSelection,
        selectedProjectKnowledge,
        projectKnowledgeEntries,
        matchedEntries,
        filteredEntries,
        injectionReport,
        degraded,
        governanceFindings,
        blockedResult: undefined,
    };
}
export function resolveDualLayerMechanisms(routeDecision, workflowContract) {
    const dlMechanisms = listMechanismLayerMaps();
    const currentRoute = routeDecision?.route ?? "";
    const currentWorkflow = workflowContract?.id ?? "";
    const dlRules = [];
    for (const mech of dlMechanisms) {
        if (mech.status !== "dual_layer_enforced" && mech.status !== "experimental_dual_layer")
            continue;
        if (mech.injected_routes && mech.injected_routes.length > 0 && currentRoute) {
            if (!mech.injected_routes.includes(currentRoute))
                continue;
        }
        if (mech.injected_workflows && mech.injected_workflows.length > 0 && currentWorkflow) {
            if (!mech.injected_workflows.includes(currentWorkflow))
                continue;
        }
        const requiredAssets = mech.template_assets.filter((ta) => ta.consumption_mode === "required");
        for (const ra of requiredAssets) {
            try {
                const content = fss.readFileSync(ra.path, "utf-8").trim();
                if (content)
                    dlRules.push(`[${mech.mechanism_name}] ${content}`);
            }
            catch (e) {
                debugLog("意图扩展: 双层机制模板加载失败 —", e);
            }
        }
    }
    return { dlRules };
}
//# sourceMappingURL=knowledge_resolution.js.map