// ── Pipeline 编排器 ──
export function createExpandPipeline(stages) {
    return {
        name: "sf_expand_pipeline",
        async run(initialContext) {
            let context = initialContext;
            for (const stage of stages) {
                const result = await stage.run(context);
                context = result.context;
                if (result.stop) {
                    return { context, stop: result.stop };
                }
            }
            return { context };
        },
    };
}
export function runExpandPipeline(context, stages) {
    return (async () => {
        let current = context;
        for (const stage of stages) {
            const result = await stage.run(current);
            current = result.context;
            if (result.stop) {
                return { context: current, stopped_by: stage.name, stop: result.stop };
            }
        }
        return { context: current };
    })();
}
// ── 路由策略计算（纯函数，可独立测试）──
export function createExpandRoutePhasePolicy(routeDecision) {
    const route = routeDecision?.route;
    const executionShape = routeDecision?.execution_shape;
    const mutationAllowed = routeDecision?.mutation_allowed === true;
    const readOnlyVerification = route === "acceptance"
        || route === "review"
        || (route === "analysis" && executionShape === "read_only_analysis")
        || (route === "operation" && (executionShape === "verification_only" || executionShape === "read_only_analysis"));
    const lightweight = !mutationAllowed
        && (readOnlyVerification
            || executionShape === "read_only_analysis"
            || executionShape === "verification_only"
            || route === "direct_answer");
    return {
        route,
        execution_shape: executionShape,
        mutation_allowed: mutationAllowed,
        lightweight,
        read_only_verification: readOnlyVerification,
        skip_workflow_contract_strict: lightweight,
        skip_input_material_hard_block: lightweight,
        skip_project_knowledge_hard_block: lightweight,
        skip_heavy_contract_gates: lightweight,
        skip_pre_implementation_gates: lightweight,
    };
}
export function computePrivacyGate(deps) {
    if (deps.phasePolicy.lightweight) {
        return {
            safeIntent: deps.redactSensitiveText(deps.intent, "intent").redacted,
            safeGoal: deps.redactSensitiveText(deps.intent.slice(0, 200), "intent_goal").redacted,
            privacyLabels: [],
            privacyRedactions: [],
            privacyFindings: [],
            hardFail: false,
            blockedSources: [],
        };
    }
    const gate = deps.evaluatePrivacyGate({
        intent: deps.intent,
        input_materials: deps.routeDecision?.input_materials?.map((m) => ({ path_or_ref: m.path ?? "" })) ?? [],
    });
    return {
        safeIntent: gate.redacted_text ?? deps.redactSensitiveText(deps.intent, "intent").redacted,
        safeGoal: deps.redactSensitiveText(deps.intent.slice(0, 200), "intent_goal").redacted,
        privacyLabels: gate.labels,
        privacyRedactions: gate.redaction_records,
        privacyFindings: gate.findings,
        hardFail: gate.hard_fail,
        blockedSources: gate.blocked_sources,
    };
}
export function validateInputMaterials(deps) {
    const { routeDecision, skipInputMaterialHardBlock, confirmations = [] } = deps;
    const contractNotes = [];
    if (!routeDecision || routeDecision.input_materials.length === 0) {
        return { blocked: false, inputMaterials: [], ingestionEvidences: [], contractNotes };
    }
    const pathMaterials = routeDecision.input_materials.filter((m) => m.path);
    if (pathMaterials.length === 0) {
        return { blocked: false, inputMaterials: [], ingestionEvidences: [], contractNotes };
    }
    const materials = pathMaterials.map((m) => deps.createInputMaterial({ path_or_ref: deps.normalizePathCandidate(m.path) }));
    const evidences = materials.map((m) => deps.createIngestionEvidence(m));
    for (const m of materials) {
        if (m.access_mode === "forbidden") {
            contractNotes.push(`[FORBIDDEN] ${m.path_or_ref}: 禁止读取`);
        }
        else if (m.trust_level === "external_unverified" || m.trust_level === "derived" || m.trust_level === "ai_generated") {
            contractNotes.push(`[Manual Confirm] ${m.path_or_ref}: 信任等级=${m.trust_level}`);
        }
    }
    const injectionPlan = deps.buildPromptInjectionPlan(materials, evidences);
    // 禁止路径检查
    const forbiddenMaterials = materials.filter((m) => m.access_mode === "forbidden");
    if (!skipInputMaterialHardBlock && forbiddenMaterials.length > 0) {
        return {
            blocked: true,
            blockReason: "输入材料包含禁止路径",
            forbiddenPaths: forbiddenMaterials.map((m) => m.path_or_ref),
            inputMaterials: materials,
            ingestionEvidences: evidences,
            promptInjectionPlan: injectionPlan,
            contractNotes,
        };
    }
    // 需确认路径检查
    const needsConfirmation = materials.filter((m) => m.access_mode !== "forbidden"
        && deps.classifyIngestionStatus(m.path_or_ref) === "requires_confirmation"
        && !confirmations.includes(m.path_or_ref));
    if (needsConfirmation.length > 0) {
        return {
            blocked: true,
            blockReason: "输入材料需要确认",
            confirmationNeeded: needsConfirmation.map((m) => m.path_or_ref),
            inputMaterials: materials,
            ingestionEvidences: evidences,
            promptInjectionPlan: injectionPlan,
            contractNotes,
        };
    }
    return {
        blocked: false,
        inputMaterials: materials,
        ingestionEvidences: evidences,
        promptInjectionPlan: injectionPlan,
        contractNotes,
    };
}
//# sourceMappingURL=expand_pipeline.js.map