// ── 必填字段列表 ──
const REQUIRED_FIELDS = [
    { key: "goal", label_zh: "目标" },
    { key: "scope", label_zh: "范围" },
    { key: "non_goals", label_zh: "非目标" },
    { key: "output_location", label_zh: "落点" },
    { key: "acceptance_criteria", label_zh: "验收标准" },
    { key: "bypass_prohibited", label_zh: "禁止绕过项" },
];
// ── 核心函数 ──
/**
 * 校验施工指令完整性：必须包含目标、范围、非目标、落点、验收、禁止绕过项。
 */
export function validateInstructionContract(contract) {
    const missing_fields = [];
    for (const { key, label_zh } of REQUIRED_FIELDS) {
        const value = contract[key];
        if (value === undefined ||
            value === null ||
            (typeof value === "string" && value.trim() === "") ||
            (Array.isArray(value) && value.length === 0)) {
            missing_fields.push(label_zh);
        }
    }
    if (missing_fields.length > 0) {
        return {
            valid: false,
            missing_fields,
            reason: `施工指令缺失必填字段: ${missing_fields.join("、")}`,
        };
    }
    return { valid: true, missing_fields: [], reason: "施工指令校验通过" };
}
/**
 * 检查施工指令完整性（用于 gate 检查）。
 */
export function checkInstructionCompleteness(contract) {
    if (!contract) {
        return {
            complete: false,
            missing: REQUIRED_FIELDS.map((f) => f.label_zh),
            severity: "hard_fail",
            reason_zh: "无施工指令，不得直接编码或实现",
        };
    }
    const validation = validateInstructionContract(contract);
    if (!validation.valid) {
        return {
            complete: false,
            missing: validation.missing_fields,
            severity: "hard_fail",
            reason_zh: `施工指令不完整，缺失: ${validation.missing_fields.join("、")}。必须先澄清或生成计划。`,
        };
    }
    return {
        complete: true,
        missing: [],
        severity: "advisory",
        reason_zh: "施工指令完整",
    };
}
/**
 * 登记施工指令候选项（用于从用户输入或计划输出中提取指令雏形）。
 */
export function registerInstructionIssueCandidate(candidate) {
    const instructionId = `instr-${candidate.task_id}-${Date.now()}`;
    return {
        instruction_id: instructionId,
        task_id: candidate.task_id,
        goal: candidate.suggested_fields.goal ?? candidate.description,
        scope: candidate.suggested_fields.scope ?? [],
        non_goals: candidate.suggested_fields.non_goals ?? [],
        output_location: candidate.suggested_fields.output_location ?? "",
        acceptance_criteria: candidate.suggested_fields.acceptance_criteria ?? [],
        bypass_prohibited: candidate.suggested_fields.bypass_prohibited ?? [
            "不可跳过验收",
            "不可跳过测试",
        ],
        confirmation_ref: candidate.suggested_fields.confirmation_ref,
        status: "draft",
        created_at: new Date().toISOString(),
    };
}
/**
 * 在实现/编码前强制执行施工指令检查。
 * 无完整指令时返回 blocked，不能假通过。
 */
export async function enforceInstructionBeforeImplementation(contract, action, taskRisk) {
    const completeness = checkInstructionCompleteness(contract);
    if (!completeness.complete) {
        return {
            allowed: false,
            reason_zh: `施工指令未就绪，禁止执行「${action}」。缺失: ${completeness.missing.join("、")}。请先调用 sf_expand 生成计划或手动补充施工指令。`,
            missing_evidence: completeness.missing,
            diagnostic_code: "SF-INSTR-5801",
        };
    }
    // status 检查：draft 状态也需确认
    if (contract && "status" in contract) {
        const status = contract.status;
        if (status === "blocked") {
            return {
                allowed: false,
                reason_zh: "施工指令状态为 blocked，不得执行",
                missing_evidence: ["instruction_status_unblocked"],
                diagnostic_code: "SF-INSTR-5802",
            };
        }
    }
    // 问题六十：高风险任务必须通过 UnsupportedClaimGate 证据门禁
    if (contract && taskRisk && (taskRisk === "high" || taskRisk === "critical")) {
        const matrixField = contract.evidence_matrix;
        if (!matrixField || Object.keys(matrixField).length === 0) {
            return {
                allowed: false,
                reason_zh: `高风险任务（${taskRisk}）缺少证据矩阵，不得执行「${action}」`,
                missing_evidence: ["evidence_matrix"],
                diagnostic_code: "SF-EVIDENCE-6002",
            };
        }
        // 调用 UnsupportedClaimGate 进行行为级检查
        const { createEvidenceGroundingSystem, } = await import("./evidence_grounding_contract.js");
        const sys = createEvidenceGroundingSystem();
        const em = matrixField;
        const claims = em.claims ?? [];
        const evidenceItems = em.evidence ?? [];
        // 注册证据到系统
        const idMap = new Map();
        for (const ev of evidenceItems) {
            const registered = sys.registry.register({
                source_type: ev.source_type,
                authority: ev.authority,
                freshness: ev.freshness,
                permission: ev.permission,
                scope: ev.scope,
                description: ev.description,
                source_ref: ev.source_ref,
            });
            idMap.set(ev.source_type + ":" + (ev.source_ref ?? ""), registered.id);
        }
        // 重建 claims 使用注册后的证据 ID
        const registeredClaims = claims.map((c) => ({
            ...c,
            evidence_ids: c.evidence_ids.length > 0
                ? c.evidence_ids
                : sys.registry.query({}).map((e) => e.id),
            category: c.category,
            risk_level: c.risk_level,
        }));
        // 使用 FactClaimVerifier 和 UnsupportedClaimGate
        const verifyResult = sys.verifier.verify(registeredClaims, taskRisk);
        const builtMatrix = sys.builder.buildContext(registeredClaims, {
            target_claims: registeredClaims.map((c) => c.claim_text),
            source_types: [], keywords: [], max_results: 20,
        });
        builtMatrix.task_id = contract.task_id ?? "";
        // 合并 unsupported_claims
        builtMatrix.unsupported_claims.push(...verifyResult.unsupported.map((c) => c.id));
        const gateResult = sys.gate.evaluate(builtMatrix, taskRisk);
        if (!gateResult.allowed) {
            return {
                allowed: false,
                reason_zh: `证据驱动门禁阻断: ${gateResult.reason_zh}`,
                missing_evidence: gateResult.missing_evidence.length > 0
                    ? gateResult.missing_evidence
                    : gateResult.unsupported_claims,
                diagnostic_code: gateResult.diagnostic_code,
            };
        }
    }
    return {
        allowed: true,
        reason_zh: "施工指令校验通过，允许执行",
        missing_evidence: [],
        diagnostic_code: "SF-INSTR-5800",
    };
}
//# sourceMappingURL=instruction_contract.js.map