/**
 * Template Mechanism Auditor
 *
 * 扫描所有模板目录，与 Consumable Asset Registry 和 Dual-Layer Mechanism Registry
 * 交叉校验，发现未映射、未消费、漂移、过度承诺等问题。
 */
import fs from "node:fs";
import path from "node:path";
import { listBuiltinConsumableAssets } from "./consumable_asset_registry.js";
import { listMechanismLayerMaps, checkDualLayerCompleteness, } from "../contracts/dual_layer_mechanism_registry.js";
import { WORKFLOW_TEMPLATE_HARD_RULES } from "./asset_manifest.js";
import { generateWorkflowRules } from "./workflow_rule_generator.js";
import { debug } from "../core/logger.js";
// ── 模板扫描目录 ──
const TEMPLATE_SCAN_DIRS = [
    "templates/procedures",
    "templates/internal/rules",
    "templates/checklists",
    "templates/artifacts/shared",
    "templates/rules/shared",
    "templates/internal/patterns",
    "templates/domain",
    "templates/artifacts/shared",
    "templates/profiles",
    "templates/patterns",
    "templates/scaffolds",
    "templates/adapters",
];
// ── 适配器承诺关键字模式 ──
const ENFORCED_PROMISE_PATTERNS = [
    { pattern: /必须阻断|硬性阻断|hard.?block|hard.?fail/i, keywords: ["必须阻断", "hard_block"] },
    { pattern: /强制执行|enforced|enforce/i, keywords: ["enforced"] },
    { pattern: /自动验证|自动校验|auto.?verif/i, keywords: ["自动验证"] },
    { pattern: /不允许|禁止|forbidden|blocked/i, keywords: ["blocked"] },
];
// ── 主审计函数 ──
/**
 * 执行模板-机制交叉审计。
 * 扫描所有模板目录，与 Consumable Asset Registry 和 Dual-Layer Mechanism Registry 交叉校验。
 * @param rootDir - 项目根目录
 * @returns 完整的审计报告
 */
export function auditTemplateMechanisms(rootDir, options) {
    debug("TemplateMechanismAuditor", "开始模板机制审计");
    const assets = listBuiltinConsumableAssets();
    const maps = listMechanismLayerMaps();
    const assetPathMap = new Map();
    for (const a of assets)
        assetPathMap.set(a.path, a);
    const mechanismMap = new Map();
    for (const m of maps)
        mechanismMap.set(m.mechanism_id, m);
    // 1. 扫描磁盘上的模板文件
    const diskTemplatePaths = scanTemplateFiles(rootDir);
    // 2. 未映射模板（磁盘上存在但未在注册表中）
    const unmappedTemplateAssets = [];
    for (const tp of diskTemplatePaths) {
        if (!assetPathMap.has(tp)) {
            unmappedTemplateAssets.push({
                path: tp,
                registered: false,
                issue: "unmapped",
            });
        }
    }
    // 3. 未消费的已注册资产（无消费者或无触发器）
    const unconsumedTemplateAssets = [];
    for (const a of assets) {
        if (a.consumers.length === 0 || !a.trigger || a.trigger.trim() === "") {
            unconsumedTemplateAssets.push({
                path: a.path,
                registered: true,
                owner_mechanism_id: a.owner_mechanism_id,
                consumption_mode: a.consumption_mode,
                consumers: a.consumers,
                trigger: a.trigger,
                issue: "unconsumed",
            });
        }
    }
    // 4. 仅模板的机制
    const templateOnlyMechanisms = [];
    // 5. 仅代码的机制
    const codeOnlyMechanisms = [];
    for (const m of maps) {
        if (m.status === "experimental_dual_layer" || m.status === "code_only_enforced")
            continue;
        const completeness = checkDualLayerCompleteness(m);
        if (!completeness.has_template_layer && completeness.has_code_layer) {
            codeOnlyMechanisms.push({
                mechanism_id: m.mechanism_id,
                priority: m.priority,
                status: m.status,
                has_template_assets: false,
                has_code_enforcers: true,
                completeness,
                issue: "code_only",
            });
        }
        else if (completeness.has_template_layer && !completeness.has_code_layer) {
            templateOnlyMechanisms.push({
                mechanism_id: m.mechanism_id,
                priority: m.priority,
                status: m.status,
                has_template_assets: true,
                has_code_enforcers: false,
                completeness,
                issue: "template_only",
            });
        }
    }
    // 6. 可能被注入的已弃用资产
    const deprecatedInjected = [];
    for (const a of assets) {
        if (a.consumption_mode === "deprecated") {
            const mechId = a.owner_mechanism_id;
            if (mechId) {
                const map = mechanismMap.get(mechId);
                if (map && map.status !== "deprecated") {
                    deprecatedInjected.push({
                        path: a.path,
                        registered: true,
                        owner_mechanism_id: mechId,
                        consumption_mode: a.consumption_mode,
                        issue: "deprecated_injected",
                    });
                }
            }
        }
    }
    // 7. required 资产无执行器
    const requiredWithoutEnforcer = [];
    for (const a of assets) {
        if (a.consumption_mode === "required" && a.owner_mechanism_id) {
            const map = mechanismMap.get(a.owner_mechanism_id);
            if (map && map.code_enforcers.length === 0) {
                requiredWithoutEnforcer.push({
                    path: a.path,
                    registered: true,
                    owner_mechanism_id: a.owner_mechanism_id,
                    consumption_mode: a.consumption_mode,
                    consumers: a.consumers,
                    trigger: a.trigger,
                    issue: "no_owner_mechanism",
                });
            }
        }
    }
    // 8. 漂移发现
    const driftFindings = computeDriftFindings(maps, assets, rootDir);
    // 9. 适配器过度承诺检查
    const overpromised = auditAdapterPromises(rootDir, mechanismMap);
    // 10. 空机制（既无模板资产也无代码执行器）
    const emptyMechanisms = [];
    for (const m of maps) {
        const completeness = checkDualLayerCompleteness(m);
        if (!completeness.has_template_layer && !completeness.has_code_layer) {
            emptyMechanisms.push({
                mechanism_id: m.mechanism_id,
                priority: m.priority,
                status: m.status,
                has_template_assets: false,
                has_code_enforcers: false,
                completeness,
                issue: "template_only",
            });
        }
    }
    // 11. 薄模板发现（厚重内容、过大模板）
    const thinTemplateFindings = computeThinTemplateFindings(rootDir);
    // 12. 工作流硬性规则发现
    const wfContent = options?.workflowContentOverride ?? generateWorkflowRules({});
    const workflowHardRuleFindings = computeWorkflowHardRuleFindings(rootDir, mechanismMap, wfContent);
    // 计算统计数量
    const allFindings = [
        ...driftFindings,
        ...unmappedTemplateAssets.map((u) => ({
            severity: "advisory",
            mechanism_id: "template_audit",
            finding_type: "asset_unconsumed",
            message: `未注册模板: ${u.path}`,
        })),
    ];
    for (const m of codeOnlyMechanisms) {
        if (m.priority === "P0" || m.priority === "P1") {
            allFindings.push({
                severity: "hard_fail",
                mechanism_id: m.mechanism_id,
                finding_type: "template_gap",
                message: `P0/P1 机制 ${m.mechanism_id} 为 code_only，必须补充模板层`,
            });
        }
    }
    for (const m of templateOnlyMechanisms) {
        if (m.priority === "P0" || m.priority === "P1") {
            allFindings.push({
                severity: "hard_fail",
                mechanism_id: m.mechanism_id,
                finding_type: "code_gap",
                message: `P0/P1 机制 ${m.mechanism_id} 为 template_only，必须补充代码层`,
            });
        }
    }
    for (const o of overpromised) {
        allFindings.push({
            severity: "hard_fail",
            mechanism_id: o.promised_mechanism_id,
            finding_type: "template_mechanism_drift",
            message: `适配器模板 ${o.source_file} 承诺 ${o.promise_keywords.join(",")} 但机制 ${o.promised_mechanism_id} 无 enforcer 支持`,
        });
    }
    for (const r of requiredWithoutEnforcer) {
        allFindings.push({
            severity: "hard_fail",
            mechanism_id: r.owner_mechanism_id ?? "unknown",
            finding_type: "template_mechanism_drift",
            message: `required 资产 ${r.path} 的机制 ${r.owner_mechanism_id} 无代码 enforcer`,
        });
    }
    // 将工作流硬性规则发现计入 hard_fail 数量
    for (const wf of workflowHardRuleFindings) {
        if (wf.severity === "hard_fail") {
            allFindings.push(wf);
        }
    }
    const hardFailCount = allFindings.filter((f) => f.severity === "hard_fail").length;
    const advisoryCount = allFindings.filter((f) => f.severity === "advisory").length;
    debug("TemplateMechanismAuditor", "审计完成", "hard_fail:", hardFailCount, "advisory:", advisoryCount);
    return {
        generated_at: new Date().toISOString(),
        root_dir: rootDir,
        total_template_files: diskTemplatePaths.length,
        total_registered_assets: assets.length,
        total_mechanisms: maps.length,
        unmapped_template_assets: unmappedTemplateAssets,
        unconsumed_template_assets: unconsumedTemplateAssets,
        template_only_mechanisms: templateOnlyMechanisms,
        code_only_mechanisms: codeOnlyMechanisms,
        overpromised_adapter_rules: overpromised,
        template_mechanism_drift: driftFindings,
        deprecated_assets_injected: deprecatedInjected,
        required_assets_without_enforcer: requiredWithoutEnforcer,
        empty_mechanisms: emptyMechanisms,
        thin_template_findings: thinTemplateFindings,
        workflow_hard_rule_findings: workflowHardRuleFindings,
        hard_fail_count: hardFailCount,
        advisory_count: advisoryCount,
    };
}
// ── 模板文件扫描器 ──
/** 扫描指定根目录下的模板文件 */
function scanTemplateFiles(rootDir) {
    const paths = [];
    for (const dir of TEMPLATE_SCAN_DIRS) {
        const fullDir = path.join(rootDir, dir);
        if (!fs.existsSync(fullDir))
            continue;
        walkDir(fullDir, rootDir, paths);
    }
    return paths.sort();
}
/** 递归遍历目录，收集模板文件路径 */
function walkDir(dir, rootDir, accumulator) {
    for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
        const full = path.join(dir, entry.name);
        if (entry.isDirectory()) {
            walkDir(full, rootDir, accumulator);
        }
        else if (entry.isFile() && /\.(md|yaml|yml|hbs|ts|js|tsx|jsx)$/.test(entry.name)) {
            accumulator.push(path.relative(rootDir, full).replace(/\\/g, "/"));
        }
    }
}
// ── 漂移发现计算 ──
/**
 * 计算模板-机制漂移发现。
 * 检查 P0/P1 机制是否为 dual_layer_enforced、模板资产是否注册、文件是否存在等。
 */
function computeDriftFindings(maps, assets, rootDir) {
    const findings = [];
    const assetPathSet = new Set(assets.map((a) => a.path));
    for (const m of maps) {
        if (m.status === "experimental_dual_layer")
            continue;
        if ((m.priority === "P0" || m.priority === "P1") && m.status !== "dual_layer_enforced" && m.status !== "code_only_enforced") {
            findings.push({
                severity: "hard_fail",
                mechanism_id: m.mechanism_id,
                finding_type: "p0_not_dual_layer",
                message: `P0/P1 机制 ${m.mechanism_id} 必须为 dual_layer_enforced，当前: ${m.status}`,
            });
        }
        for (const ta of m.template_assets) {
            if (!assetPathSet.has(ta.path)) {
                findings.push({
                    severity: "hard_fail",
                    mechanism_id: m.mechanism_id,
                    finding_type: "asset_unconsumed",
                    message: `模板资产 ${ta.path} 未在 Consumable Asset Registry 注册`,
                });
            }
            if ((m.priority === "P0" || m.priority === "P1") && !fs.existsSync(path.join(rootDir, ta.path))) {
                findings.push({
                    severity: "hard_fail",
                    mechanism_id: m.mechanism_id,
                    finding_type: "asset_unconsumed",
                    message: `模板文件不存在: ${ta.path}`,
                });
            }
        }
        if (m.status === "template_only_advisory" && m.code_enforcers.length > 0) {
            findings.push({
                severity: "hard_fail",
                mechanism_id: m.mechanism_id,
                finding_type: "template_mechanism_drift",
                message: `template_only_advisory 不应有代码 enforcer`,
            });
        }
        if (m.status === "code_only_enforced" && m.template_assets.length > 0) {
            findings.push({
                severity: "advisory",
                mechanism_id: m.mechanism_id,
                finding_type: "template_mechanism_drift",
                message: `code_only_enforced 已有模板资产，建议升级为 dual_layer_enforced`,
            });
        }
    }
    return findings;
}
// ── 适配器过度承诺检查 ──
/**
 * 检查适配器文件是否存在过度承诺（承诺强制行为但无机制支持）。
 */
function auditAdapterPromises(rootDir, maps) {
    const results = [];
    const adapterFiles = [
        "src/adapters/claude_code/hooks.ts",
        "src/adapters/claude_code/claude_md.ts",
        "src/adapters/shared/workflow_template.ts",
        "src/adapters/trae/trae_rules.ts",
        "src/adapters/codex/codex_rules.ts",
    ];
    const keywordToMechanism = [
        { keywords: ["意图路由", "intent-router"], mechanism_id: "mc-intent-router" },
        { keywords: ["工作流契约", "workflow"], mechanism_id: "mc-workflow-contract" },
        { keywords: ["知识注入", "knowledge-injection"], mechanism_id: "mc-knowledge-injection-boundary" },
        { keywords: ["工具调用", "tool-invocation"], mechanism_id: "mc-tool-invocation-contract" },
        { keywords: ["验证契约", "verify", "verifier"], mechanism_id: "mc-verifier" },
        { keywords: ["防孤岛", "main-path"], mechanism_id: "mc-main-path-integration" },
        { keywords: ["隐私", "敏感信息", "privacy"], mechanism_id: "mc-privacy-boundary" },
        { keywords: ["命令执行", "command-execution"], mechanism_id: "mc-command-execution" },
        { keywords: ["核心工程", "core-engineering"], mechanism_id: "mc-core-engineering-principles" },
        { keywords: ["交付门禁", "delivery"], mechanism_id: "mc-delivery-gate" },
        { keywords: ["任务上下文", "task-context"], mechanism_id: "mc-task-context-lifecycle" },
    ];
    for (const file of adapterFiles) {
        const fullPath = path.join(rootDir, file);
        if (!fs.existsSync(fullPath))
            continue;
        let content;
        try {
            content = fs.readFileSync(fullPath, "utf-8");
        }
        catch {
            debug("TemplateMechanismAuditor", "读取适配器文件失败", fullPath);
            continue;
        }
        for (const { keywords, mechanism_id } of keywordToMechanism) {
            for (const kw of keywords) {
                const lines = content.split("\n");
                for (const line of lines) {
                    if (!line.toLowerCase().includes(kw.toLowerCase()))
                        continue;
                    for (const { pattern, keywords: promiseKws } of ENFORCED_PROMISE_PATTERNS) {
                        if (pattern.test(line)) {
                            const map = maps.get(mechanism_id);
                            const backed = !!map && map.status === "dual_layer_enforced" && map.code_enforcers.length > 0;
                            const hasEnforcer = !!map && map.code_enforcers.length > 0;
                            if (!backed) {
                                const already = results.some((r) => r.source_file === file && r.promised_mechanism_id === mechanism_id);
                                if (!already) {
                                    results.push({
                                        source_file: file,
                                        promised_mechanism_id: mechanism_id,
                                        promise_keywords: promiseKws,
                                        backed_by_mechanism: backed,
                                        mechanism_status: map?.status,
                                        has_enforcer: hasEnforcer,
                                        issue: !map ? "drift" : "overpromised",
                                    });
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return results;
}
// ── 注入守卫 ──
/**
 * 检查资产是否允许注入到当前上下文。
 * 基于资产消费模式、所属机制状态、当前路由和工作流进行多重校验。
 * @param asset - 可消费资产引用
 * @param currentRoute - 当前路由（可选）
 * @param currentWorkflow - 当前工作流（可选）
 * @returns 注入是否允许及原因
 */
export function isInjectionAllowed(asset, currentRoute, currentWorkflow) {
    const mode = asset.consumption_mode;
    if (mode === "deprecated") {
        return { allowed: false, reason: "deprecated asset must not be injected" };
    }
    if (mode === "manual_reference") {
        return { allowed: false, reason: "manual_reference asset requires explicit request" };
    }
    if (mode === "copy_only") {
        return { allowed: false, reason: "copy_only asset is only copied on init, not injected into prompt" };
    }
    if (!asset.owner_mechanism_id) {
        return { allowed: false, reason: `asset ${asset.id} has no owner_mechanism_id` };
    }
    const maps = listMechanismLayerMaps();
    const map = maps.find((m) => m.mechanism_id === asset.owner_mechanism_id);
    if (!map) {
        return { allowed: false, reason: `owner_mechanism_id ${asset.owner_mechanism_id} not found in registry` };
    }
    if (map.status === "template_only_advisory" && mode === "required") {
        return { allowed: false, reason: `template_only_advisory mechanism ${map.mechanism_id} assets cannot be required-injected` };
    }
    if (map.status === "deprecated") {
        return { allowed: false, reason: `mechanism ${map.mechanism_id} is deprecated` };
    }
    if (map.status === "dual_layer_enforced" && currentRoute && map.injected_routes && map.injected_routes.length > 0) {
        if (!map.injected_routes.includes(currentRoute)) {
            return { allowed: false, reason: `route ${currentRoute} not in mechanism ${map.mechanism_id} injected_routes` };
        }
    }
    if (map.status === "dual_layer_enforced" && currentWorkflow && map.injected_workflows && map.injected_workflows.length > 0) {
        if (!map.injected_workflows.includes(currentWorkflow)) {
            return { allowed: false, reason: `workflow ${currentWorkflow} not in mechanism ${map.mechanism_id} injected_workflows` };
        }
    }
    if ((mode === "required" || mode === "supporting") &&
        map.status !== "dual_layer_enforced" && map.status !== "experimental_dual_layer") {
        return { allowed: false, reason: `mechanism ${map.mechanism_id} status ${map.status} does not support required/supporting injection` };
    }
    return { allowed: true };
}
// ── 薄模板发现 ──
/**
 * 检查 workflow_template.ts 中的厚重内容（工具说明/流程细节/治理闭环等）。
 */
function computeThinTemplateFindings(rootDir) {
    const findings = [];
    const wfPath = path.join(rootDir, "src/adapters/shared/workflow_template.ts");
    if (!fs.existsSync(wfPath))
        return findings;
    const content = fs.readFileSync(wfPath, "utf-8");
    const lines = content.split("\n");
    // 检查厚重清单内容（共享模板中的复选框列表）
    const thickPatterns = [
        /- \[x\].{10,}/,
        /##\s+编码规范/,
        /##\s+工程执行/,
        /步骤\s+5\.[5-8]/,
        /任务完成后，可执行治理闭环检查/,
        /四个工具按以下时机调用/,
        /sf_status\s+action=/,
        /sf_audit_sample.*时机/,
        /sf_capability_update.*confirm/,
    ];
    const hasThickContent = thickPatterns.some((p) => p.test(content));
    if (hasThickContent) {
        findings.push({
            severity: "hard_fail",
            mechanism_id: "template_audit",
            finding_type: "thick_knowledge_in_shared_template",
            message: "workflow_template.ts 包含厚重知识内容（工具说明/流程细节/治理闭环），应拆分为独立知识资产",
        });
    }
    // 逐段密度检查：任何 ### 步骤 段落超过 8 行即为厚重
    const sectionRegex = /^###\s+步骤/gm;
    let match;
    while ((match = sectionRegex.exec(content)) !== null) {
        const startIdx = match.index;
        const afterSection = content.slice(startIdx);
        const sectionLines = afterSection.split("\n");
        let bodyLen = 0;
        for (let i = 1; i < sectionLines.length; i++) {
            if (/^###\s+步骤|^##\s+/.test(sectionLines[i]))
                break;
            bodyLen++;
        }
        if (bodyLen > 8) {
            findings.push({
                severity: "hard_fail",
                mechanism_id: "template_audit",
                finding_type: "thick_knowledge_in_shared_template",
                message: "workflow_template.ts 步骤段落超过 8 行，属于厚重内容",
            });
            break;
        }
    }
    // 检查过大模板（薄化后超过 100 行）
    if (lines.length > 100) {
        findings.push({
            severity: "hard_fail",
            mechanism_id: "template_audit",
            finding_type: "template_too_thick",
            message: "workflow_template.ts 有 " + lines.length + " 行，超过 100 行上限",
        });
    }
    // 检查 ## 任务管理 section（工具 API 文档）
    if (/##\s+任务管理/.test(content)) {
        findings.push({
            severity: "hard_fail",
            mechanism_id: "template_audit",
            finding_type: "thick_knowledge_in_shared_template",
            message: "workflow_template.ts 包含 任务管理 section，属于工具文档，应迁移至知识库",
        });
    }
    return findings;
}
// ── 工作流硬性规则发现 ──
/**
 * 检查工作流模板硬性规则的一致性。
 * 校验 marker 与 manifest 的对应关系、source_ref 有效性和机制状态。
 */
function computeWorkflowHardRuleFindings(rootDir, mechanismMap, workflowContent) {
    const findings = [];
    const registeredRules = new Map(WORKFLOW_TEMPLATE_HARD_RULES.map(r => [r.rule_id, r]));
    // 收集生成输出中所有 marker（单真源方向: manifest → hardRuleTag → 输出）
    const markerIds = new Set();
    const markerMechanisms = new Map();
    const content = workflowContent ?? generateWorkflowRules({});
    const markerRegex = /@sf-hard-rule\s+id=(\S+)\s+mechanism=(\S+)/g;
    let match;
    while ((match = markerRegex.exec(content)) !== null) {
        markerIds.add(match[1]);
        markerMechanisms.set(match[1], match[2]);
    }
    // 检查 1: marker → manifest（marker 存在但未在 manifest 中注册）
    for (const markerId of markerIds) {
        if (!registeredRules.has(markerId)) {
            findings.push({
                severity: "hard_fail",
                mechanism_id: "workflow_hard_rule",
                finding_type: "unregistered_hard_rule",
                message: `@sf-hard-rule id=${markerId} 未在 WORKFLOW_TEMPLATE_HARD_RULES 中注册`,
            });
        }
    }
    // 检查 2: manifest → marker（manifest 规则在模板中无对应 marker）
    for (const rule of WORKFLOW_TEMPLATE_HARD_RULES) {
        if (!markerIds.has(rule.rule_id)) {
            findings.push({
                severity: "hard_fail",
                mechanism_id: rule.mechanism_id,
                finding_type: "unregistered_hard_rule",
                message: `manifest rule ${rule.rule_id} 在 workflow_template.ts 中无对应 @sf-hard-rule marker`,
            });
        }
    }
    // 检查 3: source_ref 文件是否存在
    for (const rule of WORKFLOW_TEMPLATE_HARD_RULES) {
        const anchorSep = rule.source_ref.indexOf("#");
        const sourceFile = anchorSep >= 0 ? rule.source_ref.substring(0, anchorSep) : rule.source_ref;
        if (!fs.existsSync(path.join(rootDir, sourceFile))) {
            findings.push({
                severity: "hard_fail",
                mechanism_id: rule.mechanism_id,
                finding_type: "unregistered_hard_rule",
                message: `manifest rule ${rule.rule_id} source_ref 文件不存在: ${sourceFile}`,
            });
        }
    }
    // 检查 4: source_ref anchor 是否与 rule_id 一致
    for (const rule of WORKFLOW_TEMPLATE_HARD_RULES) {
        const anchorSep = rule.source_ref.indexOf("#");
        const anchorId = anchorSep >= 0 ? rule.source_ref.substring(anchorSep + 1) : undefined;
        if (anchorId && anchorId !== rule.rule_id) {
            findings.push({
                severity: "hard_fail",
                mechanism_id: rule.mechanism_id,
                finding_type: "unregistered_hard_rule",
                message: `manifest rule ${rule.rule_id} source_ref anchor=${anchorId} 与 rule_id 不一致`,
            });
        }
    }
    // 检查 5: marker mechanism 是否与 manifest mechanism_id 一致
    for (const rule of WORKFLOW_TEMPLATE_HARD_RULES) {
        const markerMech = markerMechanisms.get(rule.rule_id);
        if (markerMech && markerMech !== rule.mechanism_id) {
            findings.push({
                severity: "hard_fail",
                mechanism_id: rule.mechanism_id,
                finding_type: "unregistered_hard_rule",
                message: `rule ${rule.rule_id} marker mechanism=${markerMech} vs manifest mechanism_id=${rule.mechanism_id}`,
            });
        }
    }
    // 检查 6: manifest mechanism_id 是否存在且为 dual_layer_enforced
    for (const rule of WORKFLOW_TEMPLATE_HARD_RULES) {
        const mech = mechanismMap.get(rule.mechanism_id);
        if (!mech) {
            findings.push({
                severity: "hard_fail",
                mechanism_id: rule.mechanism_id,
                finding_type: "unregistered_hard_rule",
                message: `manifest rule ${rule.rule_id} mechanism_id=${rule.mechanism_id} 未在机制注册表中找到`,
            });
        }
        else if (mech.status !== "dual_layer_enforced" && mech.status !== "experimental_dual_layer" && mech.status !== "code_only_enforced") {
            findings.push({
                severity: "hard_fail",
                mechanism_id: rule.mechanism_id,
                finding_type: "unregistered_hard_rule",
                message: `manifest rule ${rule.rule_id} mechanism_id=${rule.mechanism_id} status=${mech.status}, 应为 dual_layer_enforced`,
            });
        }
    }
    return findings;
}
//# sourceMappingURL=template_mechanism_auditor.js.map