bookworm-smart-assistant/scripts/patches/patch-sensitive-paths-delivery-pipeline.js

99 lines
3.3 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* sensitive-paths.json 扩展补丁 2026-04-25
*
* 目标: ai-delivery-pipeline/ 三区目录纳入敏感路径保护
* - staging/ 防止 Edit/Write 直接写入 (应通过 pipeline 流转)
* - quarantine/ 防止恶意隔离样本被读回 (red-team-attacker 攻击 3)
* - delivery/ 防止直接覆盖交付区 (绕过验证管道)
*
* 依据: red-team-attacker 攻击 3 [HIGH 75%] "Quarantine 恶意代码图书馆"
* red-team-logic C2 [CRITICAL] "用户编辑 quarantine 导致递归 staging"
*
* 设计:
* - 新增 3 regex 规则, 匹配 .claude/ai-delivery-pipeline/{staging,quarantine,delivery}/
* - _version bump: v3.9-s1 v3.10-s1-delivery-pipeline
*
* 幂等: 若规则已存在 ( reason 标识) 则跳过
* 原子: tmp + rename
* 回滚: .bak 保留
* 后续: 补丁完成后需 `node scripts/compile-rules.js` 刷新 rules-compiled.json
*/
'use strict';
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const TARGET = path.join(__dirname, '..', '..', 'hooks', 'rules', 'sensitive-paths.json');
const COMPILE_RULES = path.join(__dirname, '..', 'compile-rules.js');
const NEW_RULES = [
{
regex: '[\\\\/]\\.claude[\\\\/]ai-delivery-pipeline[\\\\/]staging[\\\\/]',
flags: 'i',
reason: 'AI 交付流水线 staging 区 (应通过 pipeline 流转, 禁止直写)',
},
{
regex: '[\\\\/]\\.claude[\\\\/]ai-delivery-pipeline[\\\\/]quarantine[\\\\/]',
flags: 'i',
reason: 'AI 交付流水线 quarantine 区 (防恶意样本读回 / red-team 攻击 3)',
},
{
regex: '[\\\\/]\\.claude[\\\\/]ai-delivery-pipeline[\\\\/]delivery[\\\\/]',
flags: 'i',
reason: 'AI 交付流水线 delivery 区 (禁绕过验证管道直覆盖)',
},
];
const NEW_VERSION = 'v3.10-s1-delivery-pipeline';
function main() {
if (!fs.existsSync(TARGET)) {
console.error('[patch-spaths] 目标不存在:', TARGET);
process.exit(1);
}
const raw = fs.readFileSync(TARGET, 'utf8');
const json = JSON.parse(raw);
const existingReasons = new Set(json.patterns.map(p => p.reason));
const toAdd = NEW_RULES.filter(r => !existingReasons.has(r.reason));
if (toAdd.length === 0) {
console.log('[patch-spaths] 规则已存在, 跳过');
process.exit(0);
}
// 备份
const bakPath = TARGET + '.bak.delivery-pipeline.' + new Date().toISOString().replace(/[:.]/g, '-');
fs.writeFileSync(bakPath, raw, 'utf8');
json._version = NEW_VERSION;
json.patterns.push(...toAdd);
// 原子写
const newRaw = JSON.stringify(json, null, 2) + '\n';
const tmp = TARGET + '.tmp.' + process.pid;
fs.writeFileSync(tmp, newRaw, 'utf8');
fs.renameSync(tmp, TARGET);
console.log('[patch-spaths] 追加', toAdd.length, '条规则:');
toAdd.forEach(r => console.log(' +', r.reason));
console.log('[patch-spaths] _version →', NEW_VERSION);
console.log('[patch-spaths] 备份:', path.basename(bakPath));
// 刷新编译规则缓存
if (fs.existsSync(COMPILE_RULES)) {
try {
const out = execSync('node "' + COMPILE_RULES + '"', { encoding: 'utf8' });
console.log('[patch-spaths] rules-compiled.json 已刷新');
if (out.trim()) console.log(out.trim().split('\n').slice(-3).join('\n'));
} catch (e) {
console.error('[patch-spaths] compile-rules 失败:', e.message);
}
}
}
main();