bookworm-smart-assistant/scripts/patches/patch-disambig-r89-route-self-heal.js

110 lines
4.0 KiB
JavaScript
Raw Normal View History

#!/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.<ISO>
*/
'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);
}
}