#!/usr/bin/env node /** * R89 消歧规则补丁 — 路由/消歧规则自愈场景锚定 self-healer (2026-04-25) * * 解决 audit-2026-04-25-route-disambig-d1.md Q7 缺口: * - "自动修复路由规则" → vue-expert (误路由, vue-router 歧义触发) * - "路由自愈/规则自愈" → vue-expert / api-integration-specialist * - "同步计数漂移" → reviewer-expert (应 self-healer) * - "修复元数据漂移" → reviewer-expert * * 设计要点: * - 与 R84/R86 形成 read(self-auditor) / write(self-healer) 对称 * - 动词锚定 "修复/自愈/同步/补建" + 对象锚定 "路由/规则/钩子/计数/元数据/漂移" * - penalty 覆盖 audit 报告的三类误触 agent * - 不命中通用修复场景 (必须带系统内部词汇) * * 幂等: 若 R89 已存在则跳过。 * 原子: tmp + rename。 * 备份: .bak.r89-route-self-heal. */ 'use strict'; const fs = require('fs'); const path = require('path'); const TARGET = path.join(__dirname, '..', 'disambiguation-rules.json'); const NEW_RULE = { id: 'R89', note: '路由/规则/钩子/计数 自动修复/自愈/同步 → self-healer', trigger: '(?:自动修复|自愈|同步|补建|修复|回写|刷新)(?:路由规则|消歧规则|钩子链路|融合权重|计数漂移|元数据漂移|版本号|注册表|MEMORY\\.md)' + '|(?:路由|消歧|钩子|规则|hook)\\s*(?:自愈|self\\s*heal)' + '|(?:同步|修复)\\s*(?:bookworm|booworm).{0,15}(?:计数|元数据|版本|注册)', boost: 'self-healer', agent: 'self-healer', penalty: ['vue-expert', 'api-integration-specialist', 'reviewer-expert', 'project-audit-expert'], weight: 0.55, description: '写侧自愈动词 → self-healer,与 R84/R86 (read→self-auditor) 对称,penalty vue-router 等误触', }; const NEW_CHANGELOG = 'R89: 新增 — 路由/规则/计数 自愈 → self-healer (D1 Q7 修复, 与 R84/R86 对称, penalty vue-expert/api-integration-specialist/reviewer-expert)'; function main() { if (!fs.existsSync(TARGET)) { console.error('[patch-r89] 目标文件不存在:', TARGET); process.exit(1); } const raw = fs.readFileSync(TARGET, 'utf8'); const json = JSON.parse(raw); if (!Array.isArray(json.rules)) { console.error('[patch-r89] rules 不是数组'); process.exit(1); } if (json.rules.some(r => r && r.id === 'R89')) { console.log('[patch-r89] R89 已存在,跳过'); process.exit(0); } // 备份 const bakSuffix = '.bak.r89-route-self-heal.' + new Date().toISOString().replace(/[:.]/g, '-'); fs.writeFileSync(TARGET + bakSuffix, raw, 'utf8'); console.log('[patch-r89] backup → ' + path.basename(TARGET + bakSuffix)); // 追加规则 const oldCount = json.rules.length; json.rules.push(NEW_RULE); // 更新 _meta if (!json._meta) json._meta = {}; json._meta.version = '1.5.1'; json._meta.ruleCount = json.rules.length; json._meta.description = (json._meta.description || '') + ' | v1.5.1 (' + new Date().toISOString().slice(0, 10) + '): R89 路由自愈场景修复 (D1 Q7)'; if (!Array.isArray(json._meta.changelog)) json._meta.changelog = []; json._meta.changelog.push(NEW_CHANGELOG); // 原子写入 const tmpPath = TARGET + '.tmp.' + process.pid; fs.writeFileSync(tmpPath, JSON.stringify(json, null, 2) + '\n', 'utf8'); fs.renameSync(tmpPath, TARGET); console.log('[patch-r89] applied: ' + oldCount + ' → ' + json.rules.length + ' rules'); // 清除 disambiguation-tree 缓存 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-r89] disambiguation-tree cache cleared'); } } catch (e) { console.log('[patch-r89] cache clear skipped: ' + e.message); } } if (require.main === module) { try { main(); } catch (e) { console.error('[patch-r89] FAIL:', e.message); process.exit(1); } }