#!/usr/bin/env node /** * R87 penalty 清理 + L1d 业务前缀扩展 复合补丁 (2026-04-25) * * 两项修复: * * 1. R87 penalty 去除 self-auditor (与 R86 boost 语义冲突) * - 原因: R87 触发 "bookworm 在哪/是什么/如何配置" 时 penalty self-auditor, * 但 "bookworm 自检在哪配置/自检怎么用" 这类查询依然应锚定 self-auditor, * penalty 导致 R86 boost 被抵消为负 → 误路由到 developer-expert 下游 * - 保留 project-audit-expert / reviewer-expert penalty (重型审计仍需降权) * * 2. R84 negative-lookbehind 扩展 uniapp/taro/svelte/solid/qwik * - 原因: 当前仅排除 vue/next/react/angular/nuxt 业务前缀, * "uniapp 路由消歧/taro 钩子管线/svelte 路由引擎" 等短语会被 R84 误吸锚定到 self-auditor * - 新增前缀: uniapp / uni-app / taro / svelte / solid / qwik * - 同步覆盖 R86 相同模式 (系统自检 lookbehind 不变, 仅 R84 扩展) * * 幂等: 两项修复各自 sentinel 检测;已应用则跳过。 * 原子: tmp + rename。 * 备份: .bak.r87-l1d. */ 'use strict'; const fs = require('fs'); const path = require('path'); const TARGET = path.join(__dirname, '..', 'disambiguation-rules.json'); const OLD_LOOKBEHIND = '(? r && r.id === 'R87'); const r84 = json.rules.find(r => r && r.id === 'R84'); if (!r87) { console.error('[patch-r87-l1d] R87 不存在, 放弃'); process.exit(1); } if (!r84) { console.error('[patch-r87-l1d] R84 不存在, 放弃'); process.exit(1); } const actions = []; const changelog = []; // ==== 修复 1: R87 penalty 去 self-auditor ==== if (Array.isArray(r87.penalty) && r87.penalty.includes('self-auditor')) { const before = r87.penalty.slice(); r87.penalty = r87.penalty.filter(p => p !== 'self-auditor'); actions.push('R87.penalty: [' + before.join(',') + '] → [' + r87.penalty.join(',') + ']'); changelog.push('R87: 修正 — 移除 penalty self-auditor (与 R86 boost 语义冲突, 导致查询型 self-auditor 场景误降权到 developer-expert)'); } else { console.log('[patch-r87-l1d] R87 penalty 已不含 self-auditor, 跳过修复 1'); } // ==== 修复 2: R84 trigger lookbehind 扩展 ==== if (typeof r84.trigger === 'string' && r84.trigger.includes(OLD_LOOKBEHIND) && !r84.trigger.includes('uniapp')) { r84.trigger = r84.trigger.replace(OLD_LOOKBEHIND, NEW_LOOKBEHIND); actions.push('R84.trigger lookbehind 扩展: +uniapp +uni-app +taro +svelte +solid +qwik'); changelog.push('R84: L1d 扩展 — trigger negative-lookbehind 增加 uniapp/uni-app/taro/svelte/solid/qwik 业务前缀排除, 防"uniapp 路由消歧"等误吸到 self-auditor'); } else if (r84.trigger && r84.trigger.includes('uniapp')) { console.log('[patch-r87-l1d] R84 trigger 已含 uniapp, 跳过修复 2'); } else { console.warn('[patch-r87-l1d] R84 trigger 未找到预期 lookbehind 锚点, 跳过修复 2 (可能已被其他补丁改写)'); } if (actions.length === 0) { console.log('[patch-r87-l1d] 所有修复均已生效, 无需改动'); process.exit(0); } // 备份 const bakSuffix = '.bak.r87-l1d.' + new Date().toISOString().replace(/[:.]/g, '-'); fs.writeFileSync(TARGET + bakSuffix, raw, 'utf8'); console.log('[patch-r87-l1d] backup → ' + path.basename(TARGET + bakSuffix)); // 更新 _meta if (!json._meta) json._meta = {}; json._meta.version = '1.5.2'; json._meta.description = (json._meta.description || '') + ' | v1.5.2 (' + new Date().toISOString().slice(0, 10) + '): R87 penalty 清理 + R84 L1d 业务前缀扩展'; if (!Array.isArray(json._meta.changelog)) json._meta.changelog = []; json._meta.changelog.push(...changelog); // 原子写入 const tmpPath = TARGET + '.tmp.' + process.pid; fs.writeFileSync(tmpPath, JSON.stringify(json, null, 2) + '\n', 'utf8'); fs.renameSync(tmpPath, TARGET); console.log('[patch-r87-l1d] applied:'); actions.forEach(a => console.log(' - ' + a)); // 清缓存 try { const treePath = path.join(__dirname, '..', 'disambiguation-tree.js'); delete require.cache[require.resolve(treePath)]; const tree = require(treePath); if (tree && typeof tree.clearCache === 'function') { tree.clearCache(); console.log('[patch-r87-l1d] disambiguation-tree cache cleared'); } } catch (e) { console.log('[patch-r87-l1d] cache clear skipped: ' + e.message); } } if (require.main === module) { try { main(); } catch (e) { console.error('[patch-r87-l1d] FAIL:', e.message); process.exit(1); } }