/**
 * 下一步动作规划器 — 问题六十五。
 *
 * 核心编排模块: 综合项目阶段、任务阶段、陈旧检测和禁止动作规则，
 * 生成可执行的 NextActionPlan 和 ExecutableWorkPackage。
 *
 * 不输出一句提示，而是生成一个完整的工作包。
 */
import fs from "node:fs";
import path from "node:path";
import crypto from "node:crypto";
import { detectProjectStage } from "./project_stage_detector.js";
import { detectTaskStage } from "../pipeline/task_stage_detector.js";
import { detectStaleCurrentTask } from "../pipeline/stale_current_task_detector.js";
import { TaskContextManager } from "../pipeline/task_context.js";
import { debug } from "../core/logger.js";
import { evaluateLifecycleKnowledgeDecision } from "../contracts/lifecycle_knowledge_contract.js";
import { analyzeConfigRepair } from "../config/config_auto_repair.js";
import { auditDesignImplementationTraceability, DESIGN_IMPLEMENTATION_TRACEABILITY_RECOVERY_COMMAND, DESIGN_IMPLEMENTATION_TRACEABILITY_RECOVERY_GUIDANCE, DESIGN_IMPLEMENTATION_TRACEABILITY_TEMPLATE_PATH, } from "../contracts/traceability.js";
/**
 * 判断底层项目是否为空项目（无源码标记）。
 * 用于区分 configuration_pending 中 "新空项目" vs "老项目配置未确认"。
 * 不检查 .soloforge/ 等管理文件，因为 configuration_pending 阶段 .soloforge/ 必然存在。
 * 与 config_write_boundary.ts 的 PROJECT_MARKERS 概念一致，但排除 SoloForge 自身标记。
 */
const SOURCE_MARKERS = [
    "package.json", "pom.xml", "build.gradle", "settings.gradle",
    "pyproject.toml", "go.mod", "Cargo.toml", "src", "lib", "app",
];
function isGreenfieldProject(projectPath) {
    return SOURCE_MARKERS.every(marker => !fs.existsSync(path.join(projectPath, marker)));
}
/**
 * 核心编排: 生成下一步行动计划。
 */
export async function planNextAction(projectPath) {
    debug("动作规划", "开始规划", projectPath);
    const planId = `nav-${crypto.randomUUID().slice(0, 8)}`;
    const generatedAt = new Date().toISOString();
    // 1. 检测项目阶段
    const projectStage = await detectProjectStage(projectPath);
    const stageEvidence = [`project_stage=${projectStage}`];
    // 2. 检测陈旧任务
    const stateDir = path.join(projectPath, ".soloforge", "state");
    let staleTask = null;
    let currentTaskCtx = null;
    let currentTaskId = null;
    let taskStage = null;
    if (fs.existsSync(stateDir)) {
        staleTask = await detectStaleCurrentTask(stateDir);
        if (staleTask.task_id) {
            currentTaskId = staleTask.task_id;
            currentTaskCtx = staleTask.current_task_context ?? null;
        }
        // 如果没有陈旧问题，获取当前活跃任务
        if (!staleTask.is_stale && !currentTaskCtx) {
            try {
                const manager = new TaskContextManager(stateDir);
                currentTaskCtx = await manager.getCurrentTask();
                if (currentTaskCtx) {
                    currentTaskId = currentTaskCtx.task_id;
                }
            }
            catch {
                // 状态目录存在但无活跃任务
            }
        }
        if (currentTaskCtx) {
            taskStage = detectTaskStage(currentTaskCtx);
            stageEvidence.push(`task_stage=${taskStage}`);
            stageEvidence.push(`task_status=${currentTaskCtx.status}`);
        }
    }
    // 3. 禁止动作
    const disallowedActions = computeDisallowedActions(projectStage, taskStage, currentTaskCtx, projectPath);
    // 4. 警告与证据缺口
    const warnings = computeWarnings(projectStage, taskStage, currentTaskCtx, projectPath);
    const blockingWarnings = warnings.filter((warning) => warning.code === "LIFECYCLE_KNOWLEDGE_HARD_FAIL" || warning.code === "TRACEABILITY_HARD_FAIL");
    // 5. 阻断原因
    const blockingReasons = [
        ...disallowedActions.map((da) => da.reason_zh),
        ...blockingWarnings.map((warning) => warning.message_zh),
    ];
    // 6. 工作包
    const workPackage = computeWorkPackage(projectStage, taskStage, staleTask, currentTaskCtx, projectPath, blockingWarnings);
    // 7. 推荐命令
    const recommendedCommands = computeRecommendedCommands(projectStage, taskStage, staleTask, workPackage, blockingWarnings);
    // 8. 推荐提示语
    const recommendedPrompt = computeRecommendedPrompt(projectStage, taskStage, staleTask, workPackage, blockingWarnings);
    // 9. 用户确认分级
    const confirmationDecisions = computeConfirmationDecisions(projectStage, staleTask, workPackage, disallowedActions, warnings);
    // 10. 项目知识上下文
    const projectKnowledgeContext = computeProjectKnowledgeContext(projectPath, projectStage, taskStage, recommendedPrompt);
    // 11. 置信度
    const confidence = computeConfidence(projectStage, currentTaskCtx);
    return {
        plan_id: planId,
        generated_at: generatedAt,
        project_stage: projectStage,
        task_stage: taskStage,
        current_task_id: currentTaskId,
        confidence,
        stage_evidence: stageEvidence,
        blocking_reasons: blockingReasons,
        stale_task: staleTask?.is_stale ? staleTask : null,
        work_package: workPackage,
        confirmation_decisions: confirmationDecisions,
        disallowed_actions: disallowedActions,
        recommended_commands: recommendedCommands,
        recommended_prompt_zh: recommendedPrompt,
        warnings,
        project_knowledge_context: projectKnowledgeContext,
        project_path: projectPath,
    };
}
/**
 * 计算 7 条禁止动作规则。
 */
export function computeDisallowedActions(projectStage, taskStage, ctx, _projectPath) {
    const actions = [];
    // 规则 1: 设计审计失败 → 禁止写业务代码
    if (ctx?.design_artifact_pack
        && ctx.design_artifact_pack.status !== "implementation_ready"
        && ctx.design_artifact_pack.status !== "confirmed") {
        actions.push({
            rule_id: "design_audit_fail_no_coding",
            blocked_actions: ["编码与单元测试"],
            reason_zh: "设计产物未通过审计复验，禁止写业务代码",
            evidence_field: `design_artifact_pack.status=${ctx.design_artifact_pack.status}`,
        });
    }
    // 规则 2: 配置未确认
    // 空项目不阻断 — 知识规则 "不可阻塞：因为没有源码或历史文档而阻止空项目建立基线"
    // 老项目只阻断高风险动作（编码、交付），允许需求分析和架构设计（只读规划）
    if (projectStage === "configuration_pending") {
        if (!isGreenfieldProject(_projectPath)) {
            actions.push({
                rule_id: "unconfirmed_config_no_action",
                blocked_actions: ["编码与单元测试", "联调验证"],
                reason_zh: "已有项目配置未确认，编码和交付等高风险动作暂不可执行，建议先运行 soloforge config confirm 确认关键字段",
                evidence_field: "project_stage=configuration_pending, project_has_source=true",
            });
        }
    }
    // 规则 3: 决策未确认 → 禁止定稿架构/详细设计/代码/交付
    if (ctx?.architecture_decision_workshop) {
        const workshop = ctx.architecture_decision_workshop;
        const hasUnconfirmed = Object.values(workshop.domains ?? {}).some((d) => d.status !== "confirmed" && d.status !== "not_applicable_with_reason");
        if (hasUnconfirmed) {
            actions.push({
                rule_id: "unconfirmed_decision_no_finalization",
                blocked_actions: ["编码与单元测试", "架构设计", "联调验证"],
                reason_zh: "架构决策研讨中存在未确认的决策项，禁止定稿架构/详细设计/代码和交付",
                evidence_field: "architecture_decision_workshop 含未确认域",
            });
        }
    }
    // 规则 4: 无开发切片计划 → 禁止大范围编码
    if (ctx?.expansion && !ctx.planning && taskStage === "编码与单元测试") {
        actions.push({
            rule_id: "no_slice_plan_no_wide_coding",
            blocked_actions: ["编码与单元测试"],
            reason_zh: "无开发切片计划，禁止大范围编码，建议先生成切片规划工作包",
            evidence_field: "expansion 存在但 planning 不存在",
        });
    }
    // 规则 5: repair_reverify_directive 未清零 → 禁止交付
    if (ctx?.repair_reverify_directive?.blocked) {
        actions.push({
            rule_id: "repair_directive_no_delivery",
            blocked_actions: ["联调验证"],
            reason_zh: "修复重验指令未清零，优先完成修复和复验",
            evidence_field: `repair_reverify_directive.contract_id=${ctx.repair_reverify_directive.contract_id}`,
        });
    }
    // 规则 6: 测试失败 → 禁止交付
    if (ctx?.verification_result?.status === "failed") {
        actions.push({
            rule_id: "test_fail_no_delivery",
            blocked_actions: ["联调验证"],
            reason_zh: "测试未通过，禁止交付",
            evidence_field: "verification.status=failed",
        });
    }
    // 规则 7: 本地验收缺失 → 禁止交付结论
    if (ctx?.delivery_readiness?.delivery_allowed && !ctx.local_acceptance_evidence) {
        actions.push({
            rule_id: "missing_local_acceptance_no_delivery",
            blocked_actions: ["联调验证"],
            reason_zh: "缺少本地验收证据，禁止交付结论",
            evidence_field: "local_acceptance_evidence 不存在",
        });
    }
    return actions;
}
/**
 * 计算用户确认分级。只有 must_confirm 可以阻塞推进；should_confirm 只提醒；
 * auto_resolvable 由 SoloForge 给出命令或修复路径，不要求用户先拍板。
 */
export function computeConfirmationDecisions(projectStage, staleTask, workPackage, disallowedActions, warnings) {
    const must = [];
    const should = [];
    const auto = [];
    if (staleTask?.is_stale) {
        must.push({
            id: "resolve-stale-task",
            level: "must_confirm",
            title_zh: "选择陈旧任务处理方式",
            reason_zh: staleTask.reason_zh,
            source: "stale_task",
            blocks_actions: ["需求分析", "架构设计", "编码与单元测试", "联调验证"],
            options_zh: ["恢复旧任务", "归档旧任务", "开始新任务"],
            command_hint: "soloforge next",
            if_unconfirmed_zh: "不确认处理方式时，不应让 AI 绕过当前任务指针直接开始新任务。",
        });
    }
    const hasUnconfirmedDecision = disallowedActions.some((a) => a.rule_id === "unconfirmed_decision_no_finalization");
    if (hasUnconfirmedDecision) {
        must.push({
            id: "confirm-open-decisions",
            level: "must_confirm",
            title_zh: "确认未定稿的关键决策",
            reason_zh: "架构、详细设计或代码定稿前仍存在未确认的决策项。",
            source: "decision",
            blocks_actions: ["编码与单元测试", "架构设计", "联调验证"],
            options_zh: ["确认推荐方案", "选择其他方案", "标记不适用并说明理由", "要求重新研讨"],
            command_hint: "soloforge next",
            if_unconfirmed_zh: "不确认时只能继续研讨或补证据，不得生成正式设计、代码或交付结论。",
        });
    }
    if (projectStage === "configuration_pending") {
        // 通过工作包 id 判断是否为空项目（工作包在确认计算之前已由 computeWorkPackage 生成）
        const isGreenfield = workPackage?.id === "greenfield-start";
        should.push({
            id: "confirm-project-config",
            level: "should_confirm",
            title_zh: "确认项目配置",
            reason_zh: "项目配置尚未高置信确认，SoloForge 会使用默认或推断值，可能影响技术栈过滤和命令推荐。",
            source: "config",
            blocks_actions: [],
            options_zh: isGreenfield
                ? ["使用默认配置直接开始", "稍后补充 config.yaml", "现在确认关键配置"]
                : ["现在确认配置", "先继续只读分析", "稍后补充 config.yaml"],
            command_hint: "soloforge config confirm <field> <value>",
            if_unconfirmed_zh: isGreenfield
                ? "空项目使用默认配置可直接开始开发，建议稍后补充确认关键配置。"
                : "不确认时仍可做需求分析和架构设计，但不得直接进入编码或交付。",
        });
    }
    if (workPackage?.user_confirmation_points.length) {
        const alreadyCovered = must.some((item) => item.id === "resolve-stale-task" || item.id === "confirm-open-decisions");
        if (!alreadyCovered) {
            const isGreenfieldBaseline = projectStage === "uninitialized" || projectStage === "configuration_pending";
            should.push({
                id: `confirm-${workPackage.id}`,
                level: "should_confirm",
                title_zh: isGreenfieldBaseline ? "确认新项目基线口径" : "确认下一步工作包边界",
                reason_zh: isGreenfieldBaseline
                    ? `从 0 开发时没有既有项目事实可确认，这里只确认目标、边界、技术选择和默认口径: ${workPackage.user_confirmation_points.join("；")}`
                    : workPackage.user_confirmation_points.join("；"),
                source: "work_package",
                blocks_actions: [],
                options_zh: workPackage.user_confirmation_points,
                if_unconfirmed_zh: isGreenfieldBaseline
                    ? "不确认时仍可初始化、同步模板和做只读规划；不得把自动推断当成既有系统事实。"
                    : "不确认时仍可继续只读准备，但不要扩大范围或执行高风险写入。",
            });
        }
    }
    for (const action of disallowedActions) {
        if (action.rule_id === "unconfirmed_config_no_action" || action.rule_id === "unconfirmed_decision_no_finalization")
            continue;
        const source = action.rule_id === "design_audit_fail_no_coding"
            ? "design"
            : action.rule_id === "repair_directive_no_delivery"
                ? "repair"
                : "delivery";
        auto.push({
            id: action.rule_id,
            level: "auto_resolvable",
            title_zh: action.reason_zh,
            reason_zh: action.evidence_field ? `${action.reason_zh}（${action.evidence_field}）` : action.reason_zh,
            source,
            blocks_actions: action.blocked_actions,
            options_zh: ["按推荐命令修复", "补齐证据后重新运行 soloforge next"],
            command_hint: action.rule_id === "design_audit_fail_no_coding"
                ? "soloforge audit-design-artifacts"
                : action.rule_id === "repair_directive_no_delivery"
                    ? "soloforge next"
                    : "soloforge validate",
            if_unconfirmed_zh: "这不是业务口径确认项，应先按证据修复或复验。",
        });
    }
    for (const warning of warnings) {
        if (warning.code === "CONFIG_AUTO_REPAIR_AVAILABLE") {
            auto.push({
                id: "config-auto-repair",
                level: "auto_resolvable",
                title_zh: "自动修复配置机械问题",
                reason_zh: warning.message_zh,
                source: "config",
                blocks_actions: ["需求分析", "架构设计", "编码与单元测试", "联调验证"],
                options_zh: ["运行 soloforge config repair", "修复后重新运行 soloforge validate/status/next"],
                command_hint: "soloforge config repair",
                if_unconfirmed_zh: "这是类型归一化或 evidence 重签问题，不需要业务确认。",
            });
        }
        if (warning.code === "LIFECYCLE_KNOWLEDGE_HARD_FAIL" || warning.code === "PROJECT_KNOWLEDGE_HARD_FAIL") {
            auto.push({
                id: "project-knowledge-hard-fail",
                level: "auto_resolvable",
                title_zh: "修复项目知识阻断项",
                reason_zh: warning.message_zh,
                source: "knowledge",
                blocks_actions: ["架构设计", "联调验证"],
                options_zh: ["运行项目知识审计", "按报告修复冲突或 frontmatter"],
                command_hint: "soloforge audit-project-knowledge",
                if_unconfirmed_zh: "这不是让用户选择口径，而是需要先修复规则契约或冲突。",
            });
        }
        else if (warning.code === "PROJECT_KNOWLEDGE_INDEX_ONLY") {
            should.push({
                id: "project-knowledge-index-only",
                level: "should_confirm",
                title_zh: "确认项目知识是否需要升级为规则",
                reason_zh: warning.message_zh,
                source: "knowledge",
                blocks_actions: [],
                options_zh: ["保持仅索引", "补充 frontmatter 作为可注入规则", "补充 hard rule 并复验"],
                command_hint: "soloforge audit-project-knowledge",
                if_unconfirmed_zh: "不确认时这些知识只参与检索，不会作为 hard rule 强制执行。",
            });
        }
        if (warning.code === "TRACEABILITY_HARD_FAIL") {
            auto.push({
                id: "traceability-hard-fail",
                level: "auto_resolvable",
                title_zh: "补齐需求到编码追踪矩阵",
                reason_zh: warning.recovery_zh ? `${warning.message_zh} 恢复: ${warning.recovery_zh}` : warning.message_zh,
                source: "design",
                blocks_actions: ["架构设计", "联调验证"],
                options_zh: [
                    `按模板补齐: ${warning.template_path ?? DESIGN_IMPLEMENTATION_TRACEABILITY_TEMPLATE_PATH}`,
                    "重新运行设计产物审计",
                    "按 PHASE/SLICE/DD/AC 绑定编码任务",
                ],
                command_hint: warning.recovery_command ?? DESIGN_IMPLEMENTATION_TRACEABILITY_RECOVERY_COMMAND,
                if_unconfirmed_zh: "这不是业务选择项，而是编码前的证据链缺口；不得脱离已确认设计直接实现。",
            });
        }
    }
    const blockedReason = must.length > 0 ? must.map((item) => item.title_zh).join("；") : null;
    const hasConfigRepair = auto.some((item) => item.id === "config-auto-repair");
    const recommendedAction = must.length > 0
        ? `先处理必须确认项: ${must.map((item) => item.title_zh).join("；")}`
        : hasConfigRepair
            ? "先运行 soloforge config repair 自动修复配置类型和 evidence，再重新运行 soloforge next。"
            : auto.length > 0
                ? `无需用户确认，按命令修复: ${auto.map((item) => item.command_hint).filter(Boolean).join("；")}`
                : should.length > 0
                    ? `可继续低风险工作；建议确认: ${should.map((item) => item.title_zh).join("；")}`
                    : "无需用户确认，按下一步工作包继续。";
    return {
        must_confirm: must,
        should_confirm: should,
        auto_resolvable: auto,
        blocked_reason: blockedReason,
        recommended_action: recommendedAction,
    };
}
/**
 * 根据阶段计算可执行工作包。
 */
function computeWorkPackage(projectStage, taskStage, staleTask, ctx, projectPath, blockingWarnings = []) {
    if (blockingWarnings.length > 0) {
        const hasKnowledge = blockingWarnings.some((warning) => warning.code === "LIFECYCLE_KNOWLEDGE_HARD_FAIL");
        const hasTraceability = blockingWarnings.some((warning) => warning.code === "TRACEABILITY_HARD_FAIL");
        const commands = [
            ...(hasKnowledge ? ["soloforge audit-project-knowledge"] : []),
            ...(hasTraceability ? ["soloforge audit-design-artifacts"] : []),
            "soloforge next",
        ];
        return {
            id: hasKnowledge && hasTraceability
                ? "repair-knowledge-and-traceability"
                : hasKnowledge
                    ? "repair-project-knowledge"
                    : "repair-traceability",
            goal_zh: hasKnowledge && hasTraceability
                ? "修复项目知识和追踪链路阻断项"
                : hasKnowledge
                    ? "修复项目知识阻断项"
                    : "补齐需求到编码追踪链路",
            description_zh: blockingWarnings.map((warning) => warning.message_zh).join("；"),
            action: hasKnowledge ? "初始化" : "任务规划",
            tool_name: "soloforge",
            tool_args: { commands },
            input_files: hasTraceability
                ? [
                    "docs/traceability/01-需求原型设计实现追踪矩阵.md",
                    "docs/architecture/04-开发切片计划.md",
                    "docs/architecture/**",
                ]
                : [".soloforge/knowledge/**"],
            must_read: hasTraceability
                ? [
                    "docs/traceability/01-需求原型设计实现追踪矩阵.md",
                    "docs/architecture/04-开发切片计划.md",
                    "docs/architecture/01-架构设计文档.md",
                    "docs/architecture/02-数据库设计文档.md",
                    "docs/architecture/03-API接口规格文档.md",
                ]
                : [".soloforge/knowledge/**"],
            forbidden_changes: ["写业务实现代码", "绕过 SoloForge 直接改 .soloforge/state"],
            expected_outputs: hasTraceability
                ? ["追踪矩阵登记 REQ/PROTO/ARCH/DD/PHASE/SLICE/AC", "开发切片计划声明 PHASE-* 与 SLICE-*"]
                : ["项目知识冲突清零或改为明确 conflict_group/rule_value 口径"],
            acceptance_commands: commands,
            user_confirmation_points: [],
            rollback_or_fallback: ["保留原文件备份，按审计 finding 逐项恢复"],
        };
    }
    // 陈旧任务 → 解决陈旧问题
    if (staleTask?.is_stale) {
        return {
            id: "resolve-stale-task",
            goal_zh: "解决陈旧任务指针",
            description_zh: staleTask.reason_zh,
            action: "过期状态解决",
            input_files: [],
            must_read: [".soloforge/state/current-task.json"],
            forbidden_changes: ["删除任务文件", "绕过 SoloForge 直接操作"],
            expected_outputs: ["选择: 恢复旧任务 / 归档旧任务 / 开始新任务"],
            acceptance_commands: ["soloforge next"],
            user_confirmation_points: ["确认如何处理陈旧任务"],
            rollback_or_fallback: ["恢复归档的指针文件"],
        };
    }
    // 按项目阶段分发工作包
    switch (projectStage) {
        case "uninitialized":
            return {
                id: "project-init",
                goal_zh: "初始化 SoloForge 项目配置",
                description_zh: "运行 soloforge init 初始化 .soloforge/ 目录和项目配置",
                action: "初始化",
                tool_name: "soloforge",
                tool_args: { command: "init" },
                input_files: [],
                must_read: [],
                forbidden_changes: ["写业务代码", "修改数据库结构", "修改接口语义"],
                expected_outputs: [".soloforge/config.yaml", ".soloforge/config.evidence.json"],
                acceptance_commands: ["soloforge validate"],
                user_confirmation_points: ["确认项目名称、技术栈、产品类型"],
                rollback_or_fallback: ["删除 .soloforge/ 目录重新初始化"],
            };
        case "configuration_pending": {
            if (isGreenfieldProject(projectPath)) {
                return {
                    id: "greenfield-start",
                    goal_zh: "开始新项目开发",
                    description_zh: "空项目已就绪，使用默认配置开始第一个开发任务。配置确认可随时补充。",
                    action: "需求分析",
                    tool_name: "sf_classify",
                    tool_args: {},
                    input_files: [],
                    must_read: [],
                    forbidden_changes: [],
                    expected_outputs: ["新的 TaskContext"],
                    acceptance_commands: ["soloforge next"],
                    user_confirmation_points: ["确认项目目标和技术选择（可选，稍后补充）"],
                    rollback_or_fallback: ["soloforge config confirm 补充配置"],
                };
            }
            return {
                id: "config-confirm",
                goal_zh: "确认项目配置",
                description_zh: "运行 soloforge config confirm 确认项目配置字段",
                action: "初始化",
                tool_name: "soloforge",
                tool_args: { command: "config", subcommand: "confirm" },
                input_files: [".soloforge/config.yaml"],
                must_read: [".soloforge/config.yaml", ".soloforge/config.evidence.json"],
                forbidden_changes: ["写业务代码"],
                expected_outputs: ["config.evidence.json 中所有字段 confidence=high"],
                acceptance_commands: ["soloforge validate", "soloforge stage"],
                user_confirmation_points: ["确认技术栈、产品类型、构建命令等"],
                rollback_or_fallback: ["soloforge config unset <field>"],
            };
        }
        case "knowledge_ready":
            if (!ctx) {
                return {
                    id: "start-new-task",
                    goal_zh: "开始新的开发任务",
                    description_zh: "使用需求分析提交新的开发意图，开始任务分类",
                    action: "需求分析",
                    tool_name: "sf_classify",
                    input_files: [],
                    must_read: [],
                    forbidden_changes: [],
                    expected_outputs: ["新的 TaskContext，status=classifying"],
                    acceptance_commands: ["soloforge next"],
                    user_confirmation_points: [],
                    rollback_or_fallback: [],
                };
            }
            break;
        case "design_in_progress":
            return {
                id: "complete-design",
                goal_zh: "完成设计产物并通过审计",
                description_zh: "完成架构/数据库/API 设计产物包，通过审计复验",
                action: "架构设计",
                tool_name: "sf_expand",
                input_files: [],
                must_read: ["docs/architecture/**"],
                forbidden_changes: ["写业务代码", "改数据库结构", "修改接口语义"],
                expected_outputs: ["design_artifact_pack.status=implementation_ready"],
                acceptance_commands: ["soloforge audit-design-artifacts"],
                user_confirmation_points: ["确认设计产物内容"],
                rollback_or_fallback: ["回退设计产物到草稿状态"],
            };
        case "implementation_ready":
            return {
                id: "slice-planning",
                goal_zh: "基于已通过审计的设计产物制定全项目开发切片索引",
                description_zh: "设计产物已通过审计，制定包含 PHASE-*、SLICE-*、DD-* 和 AC-* 绑定的开发切片计划后开始编码",
                action: "任务规划",
                tool_name: "sf_expand",
                input_files: [],
                must_read: [
                    "docs/architecture/01-架构设计文档.md",
                    "docs/architecture/02-数据库设计文档.md",
                    "docs/architecture/03-API接口规格文档.md",
                ],
                forbidden_changes: ["写业务代码", "改数据库结构", "修改接口语义"],
                expected_outputs: ["docs/architecture/04-开发切片计划.md", "PHASE-* / SLICE-* 切片列表", "每个切片的设计来源和验收标准"],
                acceptance_commands: ["soloforge validate"],
                user_confirmation_points: ["确认第一个切片"],
                rollback_or_fallback: ["调整切片划分"],
            };
        case "development_in_progress":
            if (taskStage === "编码与单元测试") {
                return {
                    id: "continue-coding",
                    goal_zh: "继续编码实现当前切片",
                    description_zh: "继续编码实现，完成后进行本地验证",
                    action: "编码与单元测试",
                    tool_name: "sf_implement",
                    input_files: [],
                    must_read: [],
                    forbidden_changes: [],
                    expected_outputs: ["代码变更", "执行结果"],
                    acceptance_commands: ["soloforge next"],
                    user_confirmation_points: [],
                    rollback_or_fallback: ["回退代码变更"],
                };
            }
            if (taskStage === "联调验证") {
                return {
                    id: "run-verification",
                    goal_zh: "执行本地构建和测试验证",
                    description_zh: "运行构建和测试命令验证代码变更",
                    action: "联调验证",
                    tool_name: "sf_verify",
                    input_files: [],
                    must_read: [],
                    forbidden_changes: [],
                    expected_outputs: ["verification.status=passed"],
                    acceptance_commands: ["soloforge next"],
                    user_confirmation_points: [],
                    rollback_or_fallback: ["回退代码变更重新编码"],
                };
            }
            break;
        case "delivery_ready":
            return {
                id: "delivery-acceptance",
                goal_zh: "交付验收",
                description_zh: "任务已通过验证，进行交付验收",
                action: "联调验证",
                tool_name: "sf_deliver",
                input_files: [],
                must_read: [],
                forbidden_changes: [],
                expected_outputs: ["交付记录"],
                acceptance_commands: ["soloforge status"],
                user_confirmation_points: ["确认交付内容"],
                rollback_or_fallback: ["回退交付"],
            };
        case "released":
            return {
                id: "post-release-observation",
                goal_zh: "发布后观察",
                description_zh: "发布后验证、监控观察、反馈收集、回滚预案检查",
                action: "过期状态解决",
                input_files: [],
                must_read: [],
                forbidden_changes: ["直接修改生产环境"],
                expected_outputs: ["监控报告", "用户反馈"],
                acceptance_commands: [],
                user_confirmation_points: [],
                rollback_or_fallback: ["回滚发布"],
            };
    }
    // 默认: 提示下一步
    return {
        id: "check-navigation",
        goal_zh: "查看当前状态和下一步建议",
        description_zh: "当前无特定工作包，建议运行 soloforge next 查看详细导航",
        action: "需求分析",
        input_files: [],
        must_read: [],
        forbidden_changes: [],
        expected_outputs: [],
        acceptance_commands: ["soloforge next"],
        user_confirmation_points: [],
        rollback_or_fallback: [],
    };
}
/**
 * 计算推荐命令列表。
 */
function computeRecommendedCommands(projectStage, taskStage, staleTask, workPackage, blockingWarnings = []) {
    const commands = [];
    if (staleTask?.is_stale) {
        commands.push("soloforge next  # 查看陈旧任务处理建议");
        return commands;
    }
    if (blockingWarnings.length > 0) {
        if (blockingWarnings.some((warning) => warning.code === "LIFECYCLE_KNOWLEDGE_HARD_FAIL")) {
            commands.push("soloforge audit-project-knowledge");
        }
        if (blockingWarnings.some((warning) => warning.code === "TRACEABILITY_HARD_FAIL")) {
            commands.push("soloforge audit-design-artifacts");
        }
        commands.push("soloforge next");
        return commands;
    }
    switch (projectStage) {
        case "uninitialized":
            commands.push("soloforge init");
            commands.push("soloforge init --auto  # 自动检测技术栈");
            break;
        case "configuration_pending":
            if (workPackage?.id === "greenfield-start") {
                commands.push("# 空项目已就绪，配置使用默认值");
                commands.push("soloforge next  # 查看下一步建议");
                commands.push("soloforge config confirm <field> <value>  # 可选：补充配置");
            }
            else {
                commands.push("soloforge config confirm <field> <value>");
                commands.push("soloforge config explain <field>");
            }
            break;
        case "knowledge_ready":
            if (!taskStage) {
                commands.push("# 开始新任务: 向 AI 描述你的开发意图");
            }
            break;
        case "design_in_progress":
            commands.push("soloforge audit-design-artifacts  # 检查设计产物状态");
            break;
        case "implementation_ready":
            commands.push("# 准备第一个开发切片");
            break;
        case "development_in_progress":
            commands.push("soloforge next  # 查看当前任务进度");
            break;
        case "delivery_ready":
            commands.push("soloforge next  # 确认交付");
            break;
        default:
            commands.push("soloforge next  # 查看下一步建议");
    }
    return commands;
}
/**
 * 计算推荐给 AI 的自然语言指令。
 */
function computeRecommendedPrompt(projectStage, taskStage, staleTask, workPackage, blockingWarnings = []) {
    if (staleTask?.is_stale) {
        return "检测到陈旧任务。请先运行 soloforge next 查看处理建议，选择恢复旧任务、归档旧任务或开始新任务。不要绕过 SoloForge 直接操作。";
    }
    if (blockingWarnings.length > 0) {
        const commands = [
            ...(blockingWarnings.some((warning) => warning.code === "LIFECYCLE_KNOWLEDGE_HARD_FAIL") ? ["soloforge audit-project-knowledge"] : []),
            ...(blockingWarnings.some((warning) => warning.code === "TRACEABILITY_HARD_FAIL") ? ["soloforge audit-design-artifacts"] : []),
        ];
        return `当前存在阻断项，先运行 ${commands.join(" 和 ")} 按报告修复，再重新运行 soloforge next。修复前不得开始新的编码任务。`;
    }
    switch (projectStage) {
        case "uninitialized":
            return "项目尚未初始化。请先运行 soloforge init 初始化项目配置。";
        case "configuration_pending":
            if (workPackage?.id === "greenfield-start") {
                return "空项目已就绪，配置使用默认值。你可以直接开始开发任务，也可以稍后运行 soloforge config confirm 补充配置。";
            }
            return "项目配置需要确认。请运行 soloforge config confirm 确认关键字段后再开始开发。";
        case "knowledge_ready":
            if (!taskStage)
                return "项目已就绪，可以开始新的开发任务。请描述你的开发意图。";
            return "任务进行中，请继续当前任务阶段的工作。";
        case "design_in_progress":
            return "设计产物尚未通过审计。请完成架构/数据库/API 设计，通过审计后才能开始编码。";
        case "implementation_ready":
            return "设计已通过审计。建议先制定开发切片计划，然后按切片编码。";
        case "development_in_progress":
            return "开发进行中。请继续当前任务，完成后运行验证。";
        case "delivery_ready":
            return "任务已通过验证，准备交付。请确认交付内容。";
        case "released":
            return "已发布。建议进行发布后验证、监控观察和反馈收集。";
        default:
            return "运行 soloforge next 查看详细导航建议。";
    }
}
/**
 * 计算警告信息。
 */
function computeWarnings(projectStage, taskStage, ctx, projectPath) {
    const warnings = [];
    if (projectStage === "uninitialized") {
        warnings.push({ code: "NOT_INITIALIZED", message_zh: "项目未初始化，建议先运行 soloforge init" });
    }
    try {
        const repair = analyzeConfigRepair(projectPath);
        if (repair.needs_repair && repair.auto_resolvable) {
            warnings.push({
                code: "CONFIG_AUTO_REPAIR_AVAILABLE",
                message_zh: `配置存在 ${repair.issues.length} 个可自动修复的问题，运行 soloforge config repair。`,
            });
        }
    }
    catch {
        // 配置自动修复分析失败时不影响导航。
    }
    if (ctx?.rework_history && ctx.rework_history.length >= 2) {
        warnings.push({
            code: "HIGH_REWORK_COUNT",
            message_zh: `任务已返工 ${ctx.rework_history.length} 次，请检查根因`,
        });
    }
    try {
        const decision = evaluateLifecycleKnowledgeDecision({
            projectPath,
            consumer: "soloforge_next",
            intent: `${projectStage} ${taskStage ?? ""}`,
            route: routeForStage(projectStage, taskStage),
            lifecycle_stage: projectStage === "implementation_ready" || projectStage === "development_in_progress"
                ? "implementation"
                : projectStage === "delivery_ready"
                    ? "delivery"
                    : projectStage === "design_in_progress"
                        ? "detail_design"
                        : undefined,
            record_trace: false,
        });
        const report = decision.project_knowledge;
        if (decision.hard_fail_count > 0) {
            warnings.push({
                code: "LIFECYCLE_KNOWLEDGE_HARD_FAIL",
                message_zh: `统一生命周期知识合同存在 ${decision.hard_fail_count} 个阻断项，先运行 soloforge audit-project-knowledge 查看并修复项目知识。`,
            });
        }
        else if (report.unconsumed > 0) {
            warnings.push({
                code: "PROJECT_KNOWLEDGE_INDEX_ONLY",
                message_zh: `项目自建知识中有 ${report.unconsumed} 条仅索引未触发消费；如需作为规则执行，请补充 routes/primary_triggers/enforcement。`,
            });
        }
    }
    catch {
        // 项目未初始化或知识目录不存在时不影响导航。
    }
    try {
        const traceability = auditDesignImplementationTraceability(projectPath);
        if (traceability.hard_fail_count > 0) {
            warnings.push({
                code: "TRACEABILITY_HARD_FAIL",
                message_zh: `需求/原型/设计/切片/验收追踪链路存在 ${traceability.hard_fail_count} 个阻断项，编码前必须先补齐追踪矩阵。`,
                recovery_zh: traceability.findings[0]?.recovery_zh ?? DESIGN_IMPLEMENTATION_TRACEABILITY_RECOVERY_GUIDANCE,
                recovery_command: traceability.findings[0]?.recovery_command ?? DESIGN_IMPLEMENTATION_TRACEABILITY_RECOVERY_COMMAND,
                template_path: traceability.findings[0]?.template_path ?? DESIGN_IMPLEMENTATION_TRACEABILITY_TEMPLATE_PATH,
            });
        }
    }
    catch {
        // 追踪审计失败不影响 next 输出基础导航。
    }
    return warnings;
}
function routeForStage(projectStage, taskStage) {
    if (taskStage === "代码审查")
        return "review";
    if (taskStage === "联调验证" || taskStage === "编码与单元测试")
        return "verification";
    if (taskStage === "架构设计" || taskStage === "详细设计")
        return "artifact_generation";
    switch (projectStage) {
        case "design_in_progress":
            return "artifact_generation";
        case "implementation_ready":
        case "development_in_progress":
            return "code_change";
        case "delivery_ready":
            return "delivery";
        default:
            return "analysis";
    }
}
function computeProjectKnowledgeContext(projectPath, projectStage, taskStage, prompt) {
    try {
        const stage = projectStage === "implementation_ready" || projectStage === "development_in_progress"
            ? "implementation"
            : projectStage === "delivery_ready"
                ? "delivery"
                : projectStage === "design_in_progress"
                    ? "detail_design"
                    : undefined;
        const decision = evaluateLifecycleKnowledgeDecision({
            projectPath,
            consumer: "soloforge_next",
            intent: `${projectStage} ${taskStage ?? ""} ${prompt}`,
            route: routeForStage(projectStage, taskStage),
            lifecycle_stage: stage,
            selection_limit: 6,
        });
        const report = decision.project_knowledge;
        const selection = decision.knowledge_selection;
        return {
            total: report.total,
            hard_fail_count: report.hard_fail_count,
            selected: selection.selected.map((decision) => ({
                id: decision.asset.id,
                name: decision.asset.name,
                rel_path: decision.asset.rel_path,
                consumption: decision.asset.consumption,
                status: decision.status,
                enforcement: decision.enforcement,
                reason_zh: decision.reason_zh,
                verification_command: decision.user_visible.verification_command,
            })),
            blocked: selection.blocked.map((decision) => ({
                id: decision.asset.id,
                name: decision.asset.name,
                rel_path: decision.asset.rel_path,
                reason_zh: decision.reason_zh,
                recovery: decision.user_visible.how_to_fix,
            })),
        };
    }
    catch {
        return undefined;
    }
}
/**
 * 计算阶段判断置信度。
 */
function computeConfidence(projectStage, ctx) {
    if (projectStage === "uninitialized")
        return "high";
    if (!ctx)
        return "medium";
    if (ctx.classification && ctx.route_decision)
        return "high";
    if (ctx.classification)
        return "medium";
    return "low";
}
//# sourceMappingURL=next_action_planner.js.map