// ── sf_expand 工具处理器 ──
// 从 classify_expand.ts 第 116-965 行提取。
// 系统中最复杂的工具处理器集合。
import path from "node:path";
import { promises as fsp } from "node:fs";
import { createToolRegistrar } from "../middleware.js";
import { ExpandSchema } from "../schemas.js";
import { lazyExpander, lazyDesignArtifactPack, lazyDecisionWorkshop, lazyOodSolid, lazyBackendImplementation, lazyCodeObservability, lazyTraceability, lazyInputMaterial, lazyDecision, } from "../lazy_loaders.js";
import { parseContractObject, CONTRACT_OBJECT_FIELDS, hasArchitectureIntentSignal, } from "../utils.js";
import { checkArchitectureDecisionWorkshopGate, checkArchitectureDesignGate, checkExistingSystemAnalysisGate, } from "../gate_checks.js";
import { checkDecisionSovereigntyGate, checkDetailDisciplineGate, checkFirstPrinciplesGate, checkBrainstormGate, } from "../cep_assessment.js";
import { TOOL_DIAGNOSTIC_CODES } from "../../../engine/audit/diagnostic_registry.js";
import { normalizePathCandidate } from "../../../engine/pipeline/input_material_extractor.js";
import { isSameOrDescendantPath } from "../../../engine/core/path_scope_utils.js";
import { errorMessage } from "../../../engine/core/helpers.js";
import { detectTaskStage } from "../../../engine/pipeline/task_stage_detector.js";
export async function registerExpandTool(ctx) {
    const { registerSafeTool } = createToolRegistrar(ctx);
    const { taskContext, config, knowledgeIndex, projectPath, gateway, ioController } = ctx;
    // ── sf_expand: 意图膨胀，生成结构化 prompt 并注入计划上下文 ──
    registerSafeTool("sf_expand", "将意图膨胀为结构化 prompt，包含 scope、验收标准和知识匹配。当存在计划时自动注入当前阶段上下文和输出模板", ExpandSchema, async (args) => {
        const ctx = await taskContext.load(args.task_id);
        if (!ctx || !ctx.classification) {
            return { result: { error: "任务不存在或尚未分类，请先调用 sf_classify" } };
        }
        // 合并校验 + 应用：ctx 已存储值 → args 覆盖值，统一解析和规范化
        let needsSave = false;
        for (const field of CONTRACT_OBJECT_FIELDS) {
            // args 优先，其次 ctx 已存储值
            const raw = args[field] ?? ctx[field];
            if (!raw)
                continue;
            const parsed = parseContractObject(raw, field);
            if (parsed.error)
                return { result: { error: parsed.error, status: "invalid_input" } };
            if (parsed.value) {
                ctx[field] = field === "decision_workshop"
                    ? ((await lazyDecisionWorkshop()).normalizeDecisionWorkshopContract(parsed.value, args.task_id) ?? parsed.value)
                    : parsed.value;
                needsSave = true;
            }
        }
        if (needsSave)
            await taskContext.save(ctx);
        // 状态守卫：classifying/expanding/clarifying/failed → expanding
        if (ctx.status === "classifying" || ctx.status === "clarifying" || ctx.status === "failed") {
            await taskContext.updateStatus(args.task_id, "expanding");
            ctx.status = "expanding";
        }
        else if (ctx.status !== "expanding") {
            return {
                result: { error: `任务状态 ${ctx.status} 不可膨胀，需要 classifying 或 expanding`, status: ctx.status },
            };
        }
        // 构建计划上下文（如果存在计划）
        let planContext;
        if (ctx.planning && ctx.planning.sub_tasks.length > 0 && ctx.planning.current_step_index < ctx.planning.sub_tasks.length) {
            const currentStep = ctx.planning.sub_tasks[ctx.planning.current_step_index];
            const previousOutputs = {};
            // 读取前序步骤的产出文件（P3: 产物系统）
            for (let i = 0; i < ctx.planning.current_step_index; i++) {
                const step = ctx.planning.sub_tasks[i];
                if (step.output_path) {
                    try {
                        const fs = await import("node:fs/promises");
                        const content = await fs.readFile(step.output_path, "utf-8");
                        previousOutputs[step.title] = content;
                    }
                    catch {
                        // 文件不存在则跳过
                    }
                }
            }
            planContext = { current_step: currentStep, previous_outputs: previousOutputs };
        }
        // H1: Token 预算检查 — advisory 模式，仅警告不阻断
        gateway.beginTask(args.task_id);
        let h1Warning;
        try {
            const gateResult = gateway.request("solution_brainstorm");
            if (!gateResult.allowed) {
                h1Warning = { warning: `H1 advisory: ${gateResult.reason}`, budget_remaining: gateResult.remaining_budget };
            }
        }
        catch (e) {
            h1Warning = { warning: `H1 advisory: ${errorMessage(e)}`, budget_remaining: 0 };
        }
        // H4: advisory-only — 不获取持久锁，仅检查当前锁定状态
        let h4LockWarning;
        const lockStatus = await ioController.isLocked();
        if (lockStatus.locked && lockStatus.task_id !== args.task_id) {
            h4LockWarning = `H4 advisory: 工作区已被任务 ${lockStatus.task_id} 锁定（${lockStatus.reason ?? "未知"}），当前 H4 未进入强制层`;
        }
        let expansion;
        try {
            // 检测当前任务阶段，传入知识注入管线
            const detectedStage = detectTaskStage(ctx);
            expansion = await (await lazyExpander()).expand({
                intent: ctx.intent,
                classification: ctx.classification,
                projectPath,
                config,
                knowledgeIndex,
                clarificationAnswers: args.clarification_answers,
                route_decision: ctx.classification?.route_decision,
                plan_context: planContext,
                input_material_confirmations: args.input_material_confirmations,
                task_id: args.task_id,
                brainstorm_session: ctx.brainstorm_session ?? undefined,
                task_stage: detectedStage,
            });
        }
        catch (expandErr) {
            // 尝试回退到 failed 状态，避免任务停留在 expanding
            try {
                await taskContext.updateStatus(args.task_id, "failed");
            }
            catch {
                // 状态转换非法（如已非 expanding），忽略
            }
            throw expandErr;
        }
        finally {
            if (!h1Warning)
                gateway.completeOperation();
            gateway.endTask();
        }
        expansion.task_id = args.task_id;
        const projectRoot = await fsp.realpath(projectPath);
        const referencedMaterialPaths = new Set((expansion.input_materials ?? [])
            .map((material) => material.path_or_ref)
            .filter((materialPath) => typeof materialPath === "string" && materialPath.length > 0)
            .map((materialPath) => path.resolve(projectRoot, normalizePathCandidate(materialPath))));
        const _confirmedCandidates = (args.input_material_confirmations ?? [])
            .map((materialPath) => path.resolve(projectRoot, normalizePathCandidate(materialPath)))
            .filter((absolutePath) => isSameOrDescendantPath(absolutePath, projectRoot, { caseSensitive: false }))
            .filter((absolutePath) => referencedMaterialPaths.has(absolutePath));
        const confirmedProjectSourcePaths = [];
        for (const absolutePath of _confirmedCandidates) {
            try {
                if ((await fsp.stat(absolutePath)).isFile()
                    && (await fsp.realpath(absolutePath)).startsWith(`${projectRoot}${path.sep}`)) {
                    confirmedProjectSourcePaths.push(absolutePath);
                }
            }
            catch {
                // 跳过无效路径
            }
        }
        const registerConfirmedProjectSources = (registry) => {
            for (const absolutePath of confirmedProjectSourcePaths) {
                const sourceRef = path.relative(projectRoot, absolutePath);
                registry.register({
                    source_type: "project_file",
                    evidence_role: "project_source_file",
                    authority: "authoritative",
                    freshness: "current",
                    permission: "allowed",
                    scope: "confirmed_input_material",
                    description: `已确认项目输入材料: ${sourceRef}`,
                    source_ref: sourceRef,
                });
            }
        };
        const workflowIntent = ctx.route_decision?.workflow_intent ?? ctx.classification.route_decision?.workflow_intent;
        // 问题六十: 高风险项目事实声明先过证据门，避免后续架构研讨门遮蔽无证据问题。
        let evidenceGateAlreadyChecked = false;
        {
            const evRoute = ctx.route_decision?.route ?? ctx.classification?.route_decision?.route;
            const evWorkflowIntent = ctx.route_decision?.workflow_intent ?? ctx.classification?.route_decision?.workflow_intent;
            const evRisk = (await import("../../../engine/contracts/evidence_grounding_contract.js")).assessTaskRisk(ctx.classification?.task_type, evRoute, ctx.intent);
            const isArchitectureContext = evWorkflowIntent === "architecture_design"
                || evWorkflowIntent === "existing_system_gap_analysis"
                || evRoute === "artifact_generation"
                || hasArchitectureIntentSignal(ctx.intent);
            if (isArchitectureContext && (evRisk === "high" || evRisk === "critical")) {
                const { createEvidenceGroundingSystem } = await import("../../../engine/contracts/evidence_grounding_contract.js");
                const evg = createEvidenceGroundingSystem();
                evg.registry.register({
                    source_type: "task_context",
                    evidence_role: "classification",
                    authority: "authoritative",
                    freshness: "current",
                    permission: "allowed",
                    scope: "classification",
                    description: "任务分类结果",
                    source_ref: `task:${args.task_id}`,
                });
                if (knowledgeIndex) {
                    const { project } = knowledgeIndex.getAllEntries();
                    for (const entry of project) {
                        if (entry.status !== "active")
                            continue;
                        evg.registry.register({
                            source_type: "knowledge_asset",
                            evidence_role: "template_guidance",
                            authority: "trusted",
                            freshness: "current",
                            permission: "allowed",
                            scope: entry.scope?.join(",") ?? "knowledge",
                            description: entry.name,
                            source_ref: entry.file_path,
                        });
                    }
                }
                const tdc = ctx.technology_decision_contract;
                if (tdc?.human_gate_evidence) {
                    evg.registry.register({
                        source_type: "user_confirmation",
                        evidence_role: "user_confirmation",
                        authority: "authoritative",
                        freshness: "current",
                        permission: "allowed",
                        scope: "technology_decision",
                        description: `技术决策确认: ${tdc.decision_scope ?? "general"}`,
                        source_ref: `decision:${tdc.decision_id ?? args.task_id}`,
                    });
                }
                registerConfirmedProjectSources(evg.registry);
                const evClaims = [
                    {
                        id: "claim-expand-0",
                        category: "user_confirmation",
                        claim_text: "任务路由和执行范围已确认",
                        evidence_ids: evg.registry.query({ source_type: "task_context" }).map((e) => e.id),
                        is_uncertain: false,
                        risk_level: evRisk,
                    },
                    {
                        id: "claim-expand-1",
                        category: "architecture",
                        claim_text: "技术方案基于现有系统分析",
                        evidence_ids: evg.registry.query({}).filter((e) => e.evidence_role && e.evidence_role !== "template_guidance" && e.evidence_role !== "classification").map((e) => e.id),
                        is_uncertain: false,
                        risk_level: evRisk,
                    },
                ];
                const evMatrix = evg.builder.buildContext(evClaims, {
                    target_claims: evClaims.map((c) => c.claim_text),
                    source_types: [],
                    keywords: [],
                    max_results: 10,
                });
                evMatrix.task_id = args.task_id;
                const evGate = evg.gate.evaluate(evMatrix, evRisk);
                await taskContext.setEvidenceGroundingResult(args.task_id, {
                    evidence_matrix: evMatrix,
                    evidence_gate_result: evGate,
                    unsupported_claims: evGate.unsupported_claims,
                    conflict_resolutions: evMatrix.conflicts,
                });
                if (!evGate.allowed) {
                    return {
                        result: {
                            error: `证据驱动门禁阻断: ${evGate.reason_zh}`,
                            diagnostic_code: evGate.diagnostic_code,
                            reason_zh: evGate.reason_zh,
                            unsupported_claims: evGate.unsupported_claims,
                            missing_evidence: evGate.missing_evidence,
                            status: "blocked",
                            recovery: "请提供项目文件、命令输出或其他权威证据支撑关键声明后重新 sf_expand",
                        },
                    };
                }
                evidenceGateAlreadyChecked = true;
            }
        }
        // 问题六十一: 架构设计前的六域研讨门独立执行，不得被施工指令契约有无绕过。
        let existingSourceRoot = false;
        for (const candidate of ["src", "backend", "frontend", "apps", "services"]) {
            if (await fsp.access(path.join(projectPath, candidate)).then(() => true, () => false)) {
                existingSourceRoot = true;
                break;
            }
        }
        let existingManifest = false;
        for (const candidate of ["package.json", "pom.xml", "build.gradle", "settings.gradle"]) {
            if (await fsp.access(path.join(projectPath, candidate)).then(() => true, () => false)) {
                existingManifest = true;
                break;
            }
        }
        const detectedArchitectureContext = existingSourceRoot && existingManifest
            ? "existing_system"
            : (!existingSourceRoot && !existingManifest ? "empty_project" : "new_system");
        const workshopGate = await checkArchitectureDecisionWorkshopGate({
            ctx,
            workflowIntent,
            projectContext: detectedArchitectureContext,
        });
        await taskContext.save(ctx);
        if (!workshopGate.allowed) {
            return {
                result: {
                    error: "架构设计前必须先完成六类架构决策研讨与用户确认",
                    status: "awaiting_confirmation",
                    architecture_decision_workshop: workshopGate.contract,
                    blocking_findings: workshopGate.findings,
                    next_domain: workshopGate.next_domain,
                    recovery: "请从当前待讨论域开始，提供候选方案、推荐理由、风险和用户确认后重新调用 sf_expand",
                },
            };
        }
        // 六域决策闭合后创建设计产物生命周期；正式设计与后续实现必须以其复验结果为准。
        if (workflowIntent === "architecture_design" && !ctx.design_artifact_pack) {
            const designModule = await lazyDesignArtifactPack();
            ctx.design_artifact_pack = designModule.createDesignArtifactPack(args.task_id);
            ctx.design_artifact_pack.status = "awaiting_decisions";
            ctx.design_artifact_pack.decision_workshop_ref = `task:${args.task_id}:architecture_decision_workshop`;
            ctx.design_artifact_pack.user_confirmation_ref = ctx.architecture_decision_workshop?.document_output_confirmation_ref;
            await taskContext.save(ctx);
        }
        // 问题六十一（通用）: 可组合决策包门禁
        const dwModule = await lazyDecisionWorkshop();
        const packMatch = dwModule.matchDecisionPacks({
            workflow_intent: workflowIntent,
            intent: ctx.intent,
            task_type: ctx.classification?.task_type,
        });
        // 过滤掉架构（架构由上面的专用子包处理）
        const nonArchPacks = packMatch.packs.filter((p) => p !== "architecture");
        if (nonArchPacks.length > 0) {
            const dwContract = ctx.decision_workshop ?? dwModule.createDecisionWorkshop(args.task_id, nonArchPacks, detectedArchitectureContext, packMatch.reasons.join("；"));
            const dwGate = dwModule.evaluateDecisionWorkshop(dwContract);
            ctx.decision_workshop = dwModule.applyDecisionWorkshopGate(dwContract);
            await taskContext.save(ctx);
            if (!dwGate.allowed) {
                return {
                    result: {
                        error: `${packMatch.reasons.join("；")}，必须先完成决策研讨与用户确认`,
                        status: "awaiting_confirmation",
                        decision_workshop: ctx.decision_workshop,
                        blocking_findings: dwGate.blocking_findings,
                        next_domain: dwGate.next_domain,
                        activated_packs: nonArchPacks,
                        recovery: "请从当前待讨论域开始，提供候选方案、推荐理由、风险和用户确认后重新调用 sf_expand",
                    },
                };
            }
        }
        // 问题四十九/五十: 已有架构合同或现有系统证据的进一步审查。
        const expansionRoute = expansion?.workflow_trace
            ? expansion?.workflow_trace?.route
            : undefined;
        const hasInstructionContract = !!ctx?.instruction_contract;
        if (hasInstructionContract) {
            if (expansionRoute === "artifact_generation" || expansionRoute === "analysis") {
                const archGate = await checkArchitectureDesignGate({ ctx, route: expansionRoute });
                if (!archGate.allowed) {
                    return {
                        result: {
                            error: archGate.reason_zh,
                            architecture_gate_findings: archGate.findings,
                            status: "blocked",
                            recovery: "架构设计审查未通过，请补充缺失项后重新 sf_expand",
                        },
                    };
                }
            }
            if (expansionRoute === "code_change" || expansionRoute === "artifact_generation") {
                const analysisGate = await checkExistingSystemAnalysisGate({
                    hasExistingCode: !!config?.tech_stack,
                    hasPackageJson: !!projectPath,
                    hasSrcDir: true,
                    hasAnalysis: !!ctx.existing_system_analysis,
                    hasGapAnalysis: !!ctx.requirement_gap_analysis,
                });
                if (!analysisGate.allowed) {
                    return {
                        result: {
                            error: `现有系统分析门禁未通过: ${analysisGate.reason_zh}`,
                            missing_analysis: analysisGate.missing_analysis,
                            status: "blocked",
                            recovery: "请先对现有项目执行系统分析和差距分析，再继续架构设计或编码",
                        },
                    };
                }
            }
        }
        // ── S4 gates: 轻量路径（acceptance/review/read_only）整体跳过 ──
        const isLightweightRoute = expansionRoute === "acceptance" || expansionRoute === "review"
            || expansionRoute === "direct_answer" || expansionRoute === "analysis";
        if (!isLightweightRoute) {
            // ── S4 gates: 独立于 hasInstructionContract，由 requires* 触发判定 ──
            // 问题十六: 技术选型决策主权 gate — 高影响技术决策缺证据时 blocked
            {
                const decisionGate = await checkDecisionSovereigntyGate({ ctx, route: expansionRoute });
                if (!decisionGate.allowed) {
                    return {
                        result: {
                            error: decisionGate.reason_zh,
                            status: "blocked",
                            expected_schema: decisionGate.expected_schema,
                            recovery: decisionGate.requires_human_gate ? "请提供技术决策确认证据（human_gate_evidence）" : "技术选型决策校验失败，请按照 expected_schema 格式提供 technology_decision_contract",
                        },
                    };
                }
            }
            // 问题二十六: 细节纪律 gate — 复杂任务缺关键细节时 blocked
            {
                const detailGate = await checkDetailDisciplineGate({ ctx, route: expansionRoute });
                if (!detailGate.allowed) {
                    return {
                        result: {
                            error: detailGate.reason_zh,
                            missing_details: detailGate.missing_details,
                            status: "blocked",
                            recovery: "多步骤/复杂任务缺 detail_discipline_contract，请提供后重新 sf_expand",
                        },
                    };
                }
            }
            // 问题二十七: 第一性原理 gate — 高影响任务缺推理时 blocked
            {
                const fpGate = await checkFirstPrinciplesGate({ ctx, route: expansionRoute });
                if (!fpGate.allowed) {
                    return {
                        result: {
                            error: fpGate.reason_zh,
                            failures: fpGate.failures,
                            expected_schema: fpGate.expected_schema,
                            status: "blocked",
                            recovery: "高影响任务缺 first_principles_frame，请按照 expected_schema 格式提供后重新 sf_expand",
                        },
                    };
                }
            }
            // 问题四十二(brainstorm): 脑暴契约 gate — 不确定项缺方案探索时 blocked
            {
                const brainstormGate = await checkBrainstormGate({ ctx, route: expansionRoute });
                if (!brainstormGate.allowed) {
                    return {
                        result: {
                            error: brainstormGate.reason_zh,
                            violations: brainstormGate.violations,
                            expected_schema: brainstormGate.expected_schema,
                            status: "blocked",
                            recovery: "不确定项/方案选择缺 brainstorm_session，请按照 expected_schema 格式提供后重新 sf_expand",
                        },
                    };
                }
            }
            // 问题六十六/六十七/六十八: 编码前工程约束必须聚合返回。
            // 不能让 OOD 或后端工程门禁抢先返回，遮蔽用户项目的注释/日志契约。
            {
                const preImplementationBlocks = [];
                const preImplementationPayload = {};
                const artifactDesignIntent = expansionRoute === "artifact_generation"
                    || ["architecture_design", "detailed_design", "database_design", "api_design"].includes(String(workflowIntent))
                    || /(?:架构|数据库|API|接口|OpenAPI).{0,12}(?:设计|规格|文档)|(?:设计|规格|文档).{0,12}(?:API|接口|OpenAPI)/i.test(ctx.intent);
                const isImplementationRoute = !artifactDesignIntent && (expansionRoute === "code_change"
                    || String(workflowIntent) === "backend_api_implementation"
                    || String(workflowIntent) === "frontend_business_logic"
                    || /编码|实现|开发|controller|service|component/i.test(ctx.intent));
                const traceabilityModule = await lazyTraceability();
                const traceReport = isImplementationRoute
                    ? traceabilityModule.auditDesignImplementationTraceability(projectPath)
                    : {
                        passed: true,
                        matrix_exists: false,
                        findings: [],
                        checked_files: [],
                        matrix_path: traceabilityModule.DEFAULT_DESIGN_IMPLEMENTATION_TRACEABILITY_PATH,
                    };
                if (isImplementationRoute && !traceReport.passed) {
                    ctx.traceability_binding = {
                        requirement_ids: [],
                        prototype_ids: [],
                        architecture_ids: [],
                        detail_design_ids: [],
                        phase_ids: [],
                        slice_ids: [],
                        acceptance_ids: [],
                        status: "needs_backfill",
                        findings: traceReport.findings.map((finding) => `${finding.code}: ${finding.message_zh}`),
                    };
                    await taskContext.save(ctx);
                    return {
                        result: {
                            error: "需求/原型/设计/切片/验收追踪链路未闭合，不得进入编码实现",
                            status: "blocked",
                            diagnostic_code: TOOL_DIAGNOSTIC_CODES.traceabilityMissing,
                            traceability_findings: traceReport.findings,
                            checked_files: traceReport.checked_files,
                            matrix_path: traceReport.matrix_path,
                            template_path: traceabilityModule.DESIGN_IMPLEMENTATION_TRACEABILITY_TEMPLATE_PATH,
                            recovery_command: traceabilityModule.DESIGN_IMPLEMENTATION_TRACEABILITY_RECOVERY_COMMAND,
                            recovery: `${traceabilityModule.DESIGN_IMPLEMENTATION_TRACEABILITY_RECOVERY_GUIDANCE}。不得取消任务后直接写代码，不得改用 Bash 绕过追踪矩阵。`,
                        },
                    };
                }
                const traceBindingIds = traceabilityModule.extractTraceabilityBindingIds(ctx);
                if (traceReport.matrix_exists && isImplementationRoute) {
                    const missingPrefixes = ["PHASE", "SLICE", "DD", "AC"].filter((prefix) => !traceBindingIds.some((id) => id.startsWith(`${prefix}-`)));
                    if (missingPrefixes.length > 0) {
                        ctx.traceability_binding = {
                            requirement_ids: traceBindingIds.filter((id) => id.startsWith("REQ-")),
                            prototype_ids: traceBindingIds.filter((id) => id.startsWith("PROTO-")),
                            architecture_ids: traceBindingIds.filter((id) => id.startsWith("ARCH-")),
                            detail_design_ids: traceBindingIds.filter((id) => id.startsWith("DD-")),
                            phase_ids: traceBindingIds.filter((id) => id.startsWith("PHASE-")),
                            slice_ids: traceBindingIds.filter((id) => id.startsWith("SLICE-")),
                            acceptance_ids: traceBindingIds.filter((id) => id.startsWith("AC-")),
                            status: "missing",
                            findings: missingPrefixes.map((prefix) => `编码前缺少 ${prefix}-* 绑定`),
                        };
                        await taskContext.save(ctx);
                        return {
                            result: {
                                error: "编码任务必须先绑定阶段、切片、详细设计和验收 ID",
                                status: "awaiting_traceability_binding",
                                diagnostic_code: TOOL_DIAGNOSTIC_CODES.traceabilityBindingMissing,
                                missing_prefixes: missingPrefixes,
                                matrix_path: traceReport.matrix_path,
                                template_path: traceabilityModule.DESIGN_IMPLEMENTATION_TRACEABILITY_TEMPLATE_PATH,
                                recovery_command: "sf_expand",
                                recovery: "在任务上下文或指令中明确本次实现对应的 PHASE-*、SLICE-*、DD-*、AC-*，再重新调用 sf_expand；不得脱离已确认设计直接编码，不得取消任务后改用 Bash/Edit/Write 直接实现",
                            },
                        };
                    }
                    ctx.traceability_binding = {
                        requirement_ids: traceBindingIds.filter((id) => id.startsWith("REQ-")),
                        prototype_ids: traceBindingIds.filter((id) => id.startsWith("PROTO-")),
                        architecture_ids: traceBindingIds.filter((id) => id.startsWith("ARCH-")),
                        detail_design_ids: traceBindingIds.filter((id) => id.startsWith("DD-")),
                        phase_ids: traceBindingIds.filter((id) => id.startsWith("PHASE-")),
                        slice_ids: traceBindingIds.filter((id) => id.startsWith("SLICE-")),
                        acceptance_ids: traceBindingIds.filter((id) => id.startsWith("AC-")),
                        status: "bound",
                        findings: [],
                    };
                    preImplementationPayload.traceability_binding = ctx.traceability_binding;
                }
                const oodModule = await lazyOodSolid();
                const oodGate = oodModule.evaluateOodDesignGate({
                    task_id: args.task_id,
                    intent: ctx.intent,
                    route: expansionRoute,
                    summary: ctx.ood_solid_summary,
                });
                if (oodGate.applicable) {
                    ctx.ood_solid_summary = oodGate.required_summary;
                    preImplementationPayload.ood_solid_summary = oodGate.required_summary;
                }
                if (!oodGate.allowed) {
                    preImplementationBlocks.push({
                        code: TOOL_DIAGNOSTIC_CODES.oodMissingSummary,
                        reason_zh: oodGate.reason_zh,
                    });
                }
                const backendModule = await lazyBackendImplementation();
                const backendGate = backendModule.evaluateBackendImplementationGate({
                    task_id: args.task_id,
                    intent: ctx.intent,
                    route: expansionRoute,
                    work_package: ctx.backend_implementation_work_package,
                });
                if (backendGate.applicable) {
                    ctx.backend_implementation_work_package = backendGate.work_package;
                    preImplementationPayload.backend_implementation_work_package = backendGate.work_package;
                }
                if (!backendGate.allowed) {
                    preImplementationBlocks.push({
                        code: TOOL_DIAGNOSTIC_CODES.backendMissingSummary,
                        reason_zh: backendGate.reason_zh,
                    });
                }
                if (ctx.classification.task_type !== "scaffold") {
                    const obsModule = await lazyCodeObservability();
                    const obsGate = obsModule.evaluateCodeObservabilityGate({
                        task_id: args.task_id,
                        intent: ctx.intent,
                        route: expansionRoute,
                        changed_files: ctx.execution?.changed_files,
                        work_package: ctx.code_observability_work_package,
                    });
                    if (obsGate.applicable) {
                        ctx.code_observability_work_package = obsGate.work_package;
                        preImplementationPayload.code_observability_work_package = obsGate.work_package;
                    }
                    if (!obsGate.allowed) {
                        preImplementationBlocks.push({
                            code: TOOL_DIAGNOSTIC_CODES.codeObservabilityWorkPackage,
                            reason_zh: obsGate.reason_zh,
                        });
                    }
                }
                if (Object.keys(preImplementationPayload).length > 0) {
                    await taskContext.save(ctx);
                }
                if (preImplementationBlocks.length > 0) {
                    return {
                        result: {
                            error: "编码前工程契约未全部确认，不得开始实现",
                            status: "awaiting_implementation_contracts",
                            diagnostic_codes: preImplementationBlocks.map((b) => b.code),
                            blocking_findings: preImplementationBlocks,
                            ...preImplementationPayload,
                            recovery: "请同时确认 OOD/SOLID、后端工程边界、代码注释与日志契约后重新调用 sf_expand",
                        },
                    };
                }
            }
        } // end if (!isLightweightRoute) — 轻量路径跳过 S4 gates + 编码前工程约束
        // Input Material Contract: 处理 hard-blocking 结果
        // Privacy Gate: 隐私/敏感信息策略阻断
        const isBlocked = expansion.prompt.startsWith("## 阻塞：输入材料禁止读取")
            || expansion.prompt.startsWith("## 阻塞：隐私/敏感信息策略");
        if (expansion.prompt.startsWith("## 澄清请求") && expansion.input_materials) {
            for (const m of expansion.input_materials) {
                if (m.access_mode !== "forbidden" && (await lazyInputMaterial()).classifyIngestionStatus(m.path_or_ref) === "requires_confirmation") {
                    break;
                }
            }
        }
        // 注入 H1/H4 advisory warnings
        const advisories = {};
        if (h1Warning)
            advisories.h1_advisory = h1Warning;
        if (h4LockWarning)
            advisories.h4_advisory = h4LockWarning;
        // 问题六十：证据驱动门禁 — 高风险任务必须阻断无证据声明（跳过已被上方架构早期门禁处理的场景）
        if (!evidenceGateAlreadyChecked) {
            const _evRoute = ctx.route_decision?.route ?? ctx.classification?.route_decision?.route;
            const _evRisk = (await import("../../../engine/contracts/evidence_grounding_contract.js")).assessTaskRisk(ctx.classification?.task_type, _evRoute, ctx.intent);
            if (_evRisk === "high" || _evRisk === "critical") {
                const { createEvidenceGroundingSystem } = await import("../../../engine/contracts/evidence_grounding_contract.js");
                const _evg = createEvidenceGroundingSystem();
                if (ctx.classification) {
                    _evg.registry.register({
                        source_type: "task_context",
                        evidence_role: "classification",
                        authority: "authoritative",
                        freshness: "current",
                        permission: "allowed",
                        scope: "classification",
                        description: "任务分类结果",
                        source_ref: `task:${args.task_id}`,
                    });
                }
                // 注册知识索引中的项目知识作为证据（仅项目级，不含全局通用规则）
                // 所有知识索引条目都是 template_guidance 角色，不得支撑项目事实声明
                if (knowledgeIndex) {
                    const { project } = knowledgeIndex.getAllEntries();
                    for (const entry of project) {
                        if (entry.status !== "active")
                            continue;
                        _evg.registry.register({
                            source_type: "knowledge_asset",
                            evidence_role: "template_guidance",
                            authority: "trusted",
                            freshness: "current",
                            permission: "allowed",
                            scope: entry.scope?.join(",") ?? "knowledge",
                            description: entry.name,
                            source_ref: entry.file_path,
                        });
                    }
                }
                // 技术决策契约含 human_gate_evidence → 注册为 user_confirmation（真实项目证据）
                const _tdc = ctx.technology_decision_contract;
                if (_tdc?.human_gate_evidence) {
                    _evg.registry.register({
                        source_type: "user_confirmation",
                        evidence_role: "user_confirmation",
                        authority: "authoritative",
                        freshness: "current",
                        permission: "allowed",
                        scope: "technology_decision",
                        description: `技术决策确认: ${_tdc.decision_scope ?? "general"}`,
                        source_ref: `decision:${_tdc.decision_id ?? args.task_id}`,
                    });
                }
                registerConfirmedProjectSources(_evg.registry);
                const _evClaims = [
                    {
                        id: "claim-expand-0",
                        category: "user_confirmation",
                        claim_text: "任务路由和执行范围已确认",
                        evidence_ids: _evg.registry.query({ source_type: "task_context" }).map((e) => e.id),
                        is_uncertain: false,
                        risk_level: _evRisk,
                    },
                ];
                // 只在架构设计/现有系统分析场景生成 architecture claim
                const _evWorkflowIntent = ctx.route_decision?.workflow_intent ?? ctx.classification?.route_decision?.workflow_intent;
                const _isArchitectureContext = _evWorkflowIntent === "architecture_design"
                    || _evWorkflowIntent === "existing_system_gap_analysis"
                    || _evRoute === "artifact_generation"
                    || hasArchitectureIntentSignal(ctx.intent);
                if (_isArchitectureContext) {
                    _evClaims.push({
                        id: "claim-expand-1",
                        category: "architecture",
                        claim_text: "技术方案基于现有系统分析",
                        evidence_ids: _evg.registry.query({}).filter((e) => e.evidence_role && e.evidence_role !== "template_guidance" && e.evidence_role !== "classification").map((e) => e.id),
                        is_uncertain: false,
                        risk_level: _evRisk,
                    });
                }
                const _evMatrix = _evg.builder.buildContext(_evClaims, {
                    target_claims: _evClaims.map((c) => c.claim_text),
                    source_types: [], keywords: [], max_results: 10,
                });
                _evMatrix.task_id = args.task_id;
                const _evGate = _evg.gate.evaluate(_evMatrix, _evRisk);
                // 写回 TaskContext（blocked 也保存）
                await taskContext.setEvidenceGroundingResult(args.task_id, {
                    evidence_matrix: _evMatrix,
                    evidence_gate_result: _evGate,
                    unsupported_claims: _evGate.unsupported_claims,
                    conflict_resolutions: _evMatrix.conflicts,
                });
                if (!_evGate.allowed) {
                    return {
                        result: {
                            error: `证据驱动门禁阻断: ${_evGate.reason_zh}`,
                            diagnostic_code: _evGate.diagnostic_code,
                            reason_zh: _evGate.reason_zh,
                            unsupported_claims: _evGate.unsupported_claims,
                            missing_evidence: _evGate.missing_evidence,
                            status: "blocked",
                            recovery: "请提供项目文件、命令输出或其他权威证据支撑关键声明后重新 sf_expand",
                        },
                    };
                }
                if (_evGate.requires_user_confirmation.length > 0) {
                    advisories.evidence_advisory = {
                        level: "requires_confirmation",
                        items: _evGate.requires_user_confirmation,
                        diagnostic_code: _evGate.diagnostic_code,
                    };
                }
            }
            else {
                // 低风险通用问答：标注为通用建议
                advisories.evidence_advisory = "通用建议，非项目事实；证据驱动门禁低风险放行";
            }
        } // end if (!evidenceGateAlreadyChecked)
        // 配置优先级警告
        if (expansion.config_resolution_reports && expansion.config_resolution_reports.length > 0) {
            const configWarnings = expansion.config_resolution_reports
                .filter(r => r.conflicts.length > 0)
                .map(r => r.conflicts.map(c => `${c.reason}`).join("; "));
            if (configWarnings.length > 0) {
                advisories.config_precedence_warnings = configWarnings;
            }
        }
        // 决策契约 advisory: 校验 expand 输出是否包含默认决策字段
        const decisionContract = (await lazyDecision()).validateDecisionOutput(expansion);
        if (!decisionContract.passed) {
            advisories.decision_contract_advisory = decisionContract.advisory;
        }
        // 统一持久化：load 一次，所有修改共享同一个 ctx，最后 save 一次
        // 避免 setExpansion/updateStatus/setPlanProposalGate 各自 load-save 互相覆盖
        try {
            const freshCtx = await taskContext.load(args.task_id);
            if (freshCtx) {
                // 1. 写入 expansion
                await taskContext.setExpansion(args.task_id, expansion, freshCtx);
                // 2. 写入 artifact（共享同一 ctx，不会重新 load）
                if (expansion.output_artifact_record) {
                    await taskContext.setArtifact(args.task_id, expansion.output_artifact_record, freshCtx);
                }
                // 3. 状态转换（共享 ctx，校验通过后 save）
                const nextStatus = isBlocked ? "failed"
                    : expansion.prompt.startsWith("## 澄清请求") ? "clarifying"
                        : "executing";
                await taskContext.updateStatus(args.task_id, nextStatus, freshCtx);
                // 4. 设置 plan_proposal_gate（共享 ctx，最后一次 save）
                {
                    const { evaluatePlanProposalGate, inferPlanGateTaskType } = await import("../../../engine/pipeline/plan_proposal_gate.js");
                    const routeForGate = expansion?.workflow_trace?.route ?? expansionRoute ?? "code_change";
                    const taskTypeForGate = inferPlanGateTaskType(ctx.intent);
                    const isLightweight = routeForGate === "acceptance" || routeForGate === "review"
                        || routeForGate === "direct_answer" || routeForGate === "analysis"
                        || taskTypeForGate === "local_acceptance";
                    if (isLightweight) {
                        await taskContext.setPlanProposalGate(args.task_id, {
                            passed: true,
                            plan_gate_status: "passed",
                            required_level: "brief_plan",
                            reason_zh: "轻量路径自动通过",
                            violations: [],
                            evidence_refs: [],
                            blocked_actions: [],
                        }, freshCtx);
                    }
                    else {
                        const gateResult = evaluatePlanProposalGate({
                            task_id: args.task_id,
                            task_type: taskTypeForGate,
                            user_intent: ctx.intent,
                            plan_level: "execution_plan",
                            plan_summary_zh: ctx.intent.slice(0, 200),
                            proposed_steps: [expansionRoute ?? "execute"],
                            verification_plan: (expansion.acceptance?.automated ?? []).map((a) => a.description ?? String(a)),
                            risks: [],
                            evidence_refs: expansion.matched_knowledge ?? [],
                        });
                        await taskContext.setPlanProposalGate(args.task_id, gateResult, freshCtx);
                    }
                }
            }
        }
        catch (persistErr) {
            try {
                await taskContext.updateStatus(args.task_id, "failed");
            }
            catch {
                // 状态转换非法，忽略
            }
            throw persistErr;
        }
        const expandPayload = Object.keys(advisories).length > 0
            ? { ...expansion, advisories }
            : expansion;
        return {
            result: expandPayload,
        };
    });
}
//# sourceMappingURL=expand_handler.js.map