bookworm-smart-assistant/scripts/patches/patch-disambig-r87-l1d-refinement.js

130 lines
5.1 KiB
JavaScript
Raw Normal View History

#!/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.<ISO>
*/
'use strict';
const fs = require('fs');
const path = require('path');
const TARGET = path.join(__dirname, '..', 'disambiguation-rules.json');
const OLD_LOOKBEHIND = '(?<!vue.?|vue\\s|next\\.?js?\\s|react\\s|angular\\s|nuxt\\s|项目|应用|这个)';
const NEW_LOOKBEHIND = '(?<!vue.?|vue\\s|next\\.?js?\\s|react\\s|angular\\s|nuxt\\s|uniapp\\s|uni-app\\s|taro\\s|svelte\\s|solid\\s|qwik\\s|项目|应用|这个)';
function main() {
if (!fs.existsSync(TARGET)) {
console.error('[patch-r87-l1d] 目标文件不存在:', TARGET);
process.exit(1);
}
const raw = fs.readFileSync(TARGET, 'utf8');
const json = JSON.parse(raw);
if (!Array.isArray(json.rules)) {
console.error('[patch-r87-l1d] rules 不是数组');
process.exit(1);
}
const r87 = json.rules.find(r => 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);
}
}