bookworm-smart-assistant/scripts/patches/patch-sensitive-paths-delivery-pipeline.js
Bookworm Admin b7a8e29d21 release: v6.7.0 - OTA E2E test release
- VERSION file as authoritative version source
- export.mjs reads VERSION with package.json fallback
- bw-ota.ps1 DryRun mode for safe testing
- auto-setup.ps1 bumped to v3.2.0 (Phase 8 OTA)
2026-04-27 17:59:44 +08:00

99 lines
3.3 KiB
JavaScript

#!/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();