/**
 * 基础场景矩阵注册表 — 发布门禁
 *
 * 七个场景 (A-G) 覆盖 基础集成路径。
 * 发布门禁通过 validate-release 验证每个就绪的场景。
 */
import { runScenarioSourceExtraction, runScenarioCodeChange, runScenarioPrivacyGate, runScenarioCommandValidation, runScenarioBlockedFeedback, runScenarioRouteDecision, } from "./foundation_scenario_runners.js";
import { errorMessage } from "../core/helpers.js";
/** 基础场景矩阵 */
export const FOUNDATION_SCENARIOS = [
    {
        scenario_id: "A",
        scenario_name: "源码包 → 原型说明",
        description: "source_extraction 路由：zip 输入 → 提取 → 生成原型说明，不修改业务源码",
        fixture_status: "ready",
        command_or_entry: "sf_classify + sf_expand with source_extraction route",
        expected_evidence: [
            "route_decision.route=source_extraction",
            "expansion.prompt 不含代码修改指令",
            "output_artifact.kind=prototype_spec",
            "原型说明模版 必须被注入",
        ],
        pass_fail_rules: [
            "route=source_extraction",
            "execution_shape=single_artifact",
            "mutation_allowed=false",
            "input_materials 包含 archive 路径",
            "input_materials read_only/input_only",
            "workflow_trace 存在 (WorkflowContract)",
            "workflow_trace.workflow_id=wf-source-extraction",
            "injection_report 存在",
            "missing_required_knowledge=[]",
            "injected/matched knowledge 包含 原型说明模版.md",
            "injected/matched knowledge 包含 源码原型交付流程.md",
            "output_artifact_record.kind=prototype_spec",
            "output_artifact_record.path 在 .soloforge/output/**",
            "prompt 不要求修改 src/ (template=source_extraction_prompt)",
            "prompt 不默认要求编译/测试",
            "artifact_ready 中文反馈合法",
            "src/** 快照 before/after 未变化 (mutation_allowed=false)",
            "ingestion_evidences 存在且包含 archive",
        ],
    },
    {
        scenario_id: "B",
        scenario_name: "普通 code_change",
        description: "code_execution 路由：普通开发任务走完整 classify→expand→execute→verify→learn 流程",
        fixture_status: "ready",
        command_or_entry: "sf_classify + sf_expand + sf_verify + sf_learn",
        expected_evidence: [
            "route_decision.route=code_change",
            "execution_shape=code_execution",
            "workflow 包含 required_mechanisms",
            "verify_commands 非空",
            "sf_learn 返回 passed 或 retry_hint",
        ],
        pass_fail_rules: [
            "code_execution 必须走 workflow code_change 且 mutation_allowed=true",
            "WorkflowContract 存在且 required_mechanisms 非空",
            "VerificationPlan 存在，build/test commands 非空",
            "VerificationResult 是独立对象，不得复用 VerificationPlan",
            "verification_executed=false 时 overall_passed=false",
            "required knowledge 缺失必须报错 (完整链路通过)",
            "verify 不允许 skip build+test",
            "ScopeLease declared_scope 内通过",
            "declared_scope 外文件被检测",
            "orphanGate 能检测孤岛/无主链路接入",
            "workflow_trace 存在 (WorkflowContract)",
            "缺 VerificationResult 不得 completed",
        ],
    },
    {
        scenario_id: "C",
        scenario_name: "敏感材料输入",
        description: "外部材料摄取：含 secret/credential 的输入被 privacy gate 拦截",
        fixture_status: "ready",
        command_or_entry: "sf_expand with secret-containing input_material",
        expected_evidence: [
            "privacy_gate.hard_fail=true",
            "secret/credential → throw 或 blocked",
            "redaction_record 记录",
        ],
        pass_fail_rules: [
            "secret 不得进入 prompt",
            "credential 路径必须被拦截",
            "PII 必须被脱敏",
        ],
    },
    {
        scenario_id: "D",
        scenario_name: "命令验证",
        description: "命令执行契约：destructive command 被 blocked，unclassified command 被 rejected",
        fixture_status: "ready",
        command_or_entry: "validateCommand with destructive/unclassified commands",
        expected_evidence: [
            "destructive command → must_confirm",
            "unclassified command → blocked",
            "CommandClassification 有 tier",
        ],
        pass_fail_rules: [
            "destructive command 不得自动执行",
            "高风险命令需要人工确认",
            "forbidden command 必须被拦截",
        ],
    },
    {
        scenario_id: "E",
        scenario_name: "模板机制一致性",
        description: "所有 dual_layer_enforced 机制有模板层 + 机制层 + 测试",
        fixture_status: "ready",
        command_or_entry: "validate-mechanisms + audit-template-mechanisms",
        expected_evidence: [
            "所有机制 layer_status=dual_layer_enforced",
            "模板资产文件存在",
            "consumable_asset_registry 注册",
            "测试文件存在",
        ],
        pass_fail_rules: [
            "no code_only_enforced",
            "no template_only_advisory",
            "no empty_mechanisms",
            "所有 P0 必须双-layer",
        ],
    },
    {
        scenario_id: "F",
        scenario_name: "失败/阻断反馈",
        description: "验证失败时用 blocked 而非 verification_summary，sf_verify failedChecks → kind=blocked",
        fixture_status: "ready",
        command_or_entry: "sf_verify with failed checks",
        expected_evidence: [
            "feedback.kind=blocked (not verification_summary)",
            "failedChecks > 0",
            "user sees blocked status",
            "ToolInvocationViolation hard_fail",
            "gc-verification-summary-masking hard_fail",
        ],
        pass_fail_rules: [
            "failedChecks > 0 时 kind 必须为 blocked",
            "sf_verify 在 sf_expand 前调用 → ToolInvocationViolation",
            "ToolInvocationViolation hard_fail",
            "blocked UserFeedbackMessage 通过验证",
            "degradation UserFeedbackMessage 覆盖",
            "human_required UserFeedbackMessage 覆盖",
            "verification_summary + unverified + risks → gc-verification-summary-masking hard_fail",
            "blocked 反馈必须包含中文模板",
            "sf_verify 在 forbidden 中 → violation",
            "sf_verify 缺少授权 → missing_authorization violation",
        ],
    },
    {
        scenario_id: "G",
        scenario_name: "入口自然语言语义路由与 RouteDecision 合同",
        description: "验证自然语言语义路由和 RouteDecision 主链路事实合同：多后缀归档识别、反向语义优先、缺路径澄清、expand 消费、TaskContext 持久化、dist 冒烟",
        fixture_status: "ready",
        command_or_entry: "sf_classify + sf_expand + route_decision contract check + dist import smoke",
        expected_evidence: [
            "route_decision.route=source_extraction for archive intents",
            "route_decision.route=skip_chat/direct_answer for non-SoloForge intents",
            "route_decision.missing_required_inputs non-empty when path missing",
            "expand consumes route_decision, no re-routing",
            "TaskContext persists route_decision + workflow_trace",
            "dist dynamic import smoke passes",
            "UserPromptSubmit outputs structured RouteDecision additionalContext",
            "hook/classify route_decision consistency",
            "sf_verify detects missing route_decision",
            "sf_verify detects workflow_trace mismatch",
            "sf_verify detects ignored missing_required_inputs",
        ],
        pass_fail_rules: [
            "archive .zip/.tar.gz/.7z/.war 路由到 source_extraction",
            "portal-ui.zip 提取原型说明 -> source_extraction + single_artifact",
            "缺路径 -> source_extraction + missing_required_inputs",
            "不用 SoloForge -> skip_chat/direct_answer, 不得 source_extraction",
            "route_decision.evidence 非空",
            "route_decision.rejected_routes 字段存在",
            "route_decision.scope 存在且 read_only 与 mutation_allowed 一致",
            "expand 消费 route_decision，prompt_template=source_extraction_prompt",
            "expand workflow_trace.route=source_extraction",
            "expand input_materials 保留 archive",
            "expand output_artifact.kind=prototype_spec",
            "expand missing_required_inputs 不被忽略",
            "classify -> expand 后 TaskContext 可读同一份 route_decision",
            "TaskContext setExpansion 后 route_decision + workflow_trace 未丢失且一致",
            "dist 动态 import 冒烟通过，至少使用非'前端应用'的归档后缀样本",
            "UserPromptSubmit structured additionalContext 包含 route/shape/mutation/materials/output_artifact/missing_inputs/prompt_template/confidence/evidence/rejected/conflicts",
            "skip_chat/direct_answer 不输出 sf_classify 指令",
            "hook routeDecision 与 sf_classify route_decision 一致",
            "compareHookAndClassifyRouteDecision 检测路由不一致 → hard_fail",
            "sf_verify 检测 route_decision 丢失 → hard_fail",
            "sf_verify 检测 workflow_trace.route 不一致 → hard_fail",
            "sf_verify 检测 missing_required_inputs 被忽略 → blocked",
            "sf_verify source_extraction mutation_allowed 被升级 → hard_fail",
            "sf_verify 正常 source_extraction 链路合同检查通过",
            "sf_verify 检测 output_artifact.kind 不一致 → hard_fail",
            "sf_verify 检测 output_artifact 缺失 → hard_fail",
            "sf_verify 检测 constraints 被清空/丢失 → hard_fail",
            "sf_verify 检测 source_extraction no_mutation 约束丢失 → hard_fail",
            "sf_verify 检测 input_materials 存在但 expansion_input_materials 缺失 → blocked",
            "sf_verify 真实工具路径检测 expansion constraints 被覆盖 → hard_fail",
        ],
    },
];
// ── 场景查询 ──
/** 校验场景验证结果是否覆盖所有必需场景 ID，返回缺失列表 */
export function validateRequiredScenarioCoverage(results, requiredIds) {
    const presentIds = new Set(results.map(s => s.scenario_id));
    const missing = requiredIds.filter(id => !presentIds.has(id));
    return { pass: missing.length === 0, missing };
}
/** 列出所有 基础场景 */
export function listFoundationScenarios() {
    return [...FOUNDATION_SCENARIOS];
}
/** 按场景 ID 查找场景 */
export function getScenarioById(id) {
    return FOUNDATION_SCENARIOS.find(s => s.scenario_id === id);
}
/** 验证所有 基础场景并返回逐场景验证结果 */
export async function validateFoundationScenarios(mechanismsPass, auditPass, _ownershipPass) {
    const results = [];
    const runnerMap = {
        A: runScenarioSourceExtraction,
        B: runScenarioCodeChange,
        C: runScenarioPrivacyGate,
        D: runScenarioCommandValidation,
        F: runScenarioBlockedFeedback,
        G: runScenarioRouteDecision,
    };
    for (const scenario of FOUNDATION_SCENARIOS) {
        if (scenario.fixture_status === "pending") {
            results.push({
                scenario_id: scenario.scenario_id,
                scenario_name: scenario.scenario_name,
                fixture_status: scenario.fixture_status,
                status: "FAIL",
                evidence: "场景 fixture_status=pending，未就绪",
                rules: [],
            });
            continue;
        }
        if (scenario.scenario_id === "E") {
            const passed = mechanismsPass && auditPass;
            results.push({
                scenario_id: scenario.scenario_id,
                scenario_name: scenario.scenario_name,
                fixture_status: scenario.fixture_status,
                status: passed ? "PASS" : "FAIL",
                evidence: passed ? "所有机制 dual_layer_enforced，模板审计通过" : "机制验证或模板审计失败",
                rules: [
                    { rule: "no code_only_enforced / no template_only_advisory / no empty_mechanisms", status: mechanismsPass ? "PASS" : "FAIL", evidence: `validateMechanismLayerMaps: mechanismsPass=${mechanismsPass}` },
                    { rule: "所有 P0 必须双-layer", status: auditPass ? "PASS" : "FAIL", evidence: `auditTemplateMechanisms: auditPass=${auditPass}` },
                ],
            });
            continue;
        }
        const runner = runnerMap[scenario.scenario_id];
        if (!runner) {
            results.push({ scenario_id: scenario.scenario_id, scenario_name: scenario.scenario_name, fixture_status: scenario.fixture_status, status: "FAIL", evidence: "未知场景", rules: [] });
            continue;
        }
        try {
            const ruleResults = await runner();
            const allPass = ruleResults.every(r => r.status === "PASS");
            const failCount = ruleResults.filter(r => r.status === "FAIL").length;
            results.push({
                scenario_id: scenario.scenario_id,
                scenario_name: scenario.scenario_name,
                fixture_status: scenario.fixture_status,
                status: allPass ? "PASS" : "FAIL",
                evidence: allPass ? `${ruleResults.length}/${ruleResults.length} 规则通过` : `${failCount}/${ruleResults.length} 规则失败`,
                rules: ruleResults,
            });
        }
        catch (err) {
            results.push({ scenario_id: scenario.scenario_id, scenario_name: scenario.scenario_name, fixture_status: scenario.fixture_status, status: "FAIL", evidence: `运行器异常: ${errorMessage(err)}`, rules: [] });
        }
    }
    return results;
}
//# sourceMappingURL=foundation_scenario_registry.js.map