#!/usr/bin/env node /** * Patch v6.6-rc2-03 · 宪法闭环度细则 + log-rotator 扩展 * 代号 v6.6-rc2-20260422-1859 * * 1. constitution/anti-arrogance.md 追加"闭环度 · Agent 信任边界"节 * sentinel: ... * 插入位置: "10 类典型失败" 标题之前 (生效清单之后) * 2. hooks/log-rotator.js 正则扩展, 让 agent-returns-*.jsonl + agent-returns.jsonl 纳入轮转 * sentinel: AGENT_RETURNS_ROTATE_V66 * 保留期沿用现有 7 天约定 (原 prompt 30 天已就地对齐, 见失败透明说明) * * 回滚: pwsh scripts/rollback-v6.6-rc2.ps1 -Scope all * 重签: node hooks/integrity-check.js --generate */ 'use strict'; const fs = require('fs'); const path = require('path'); const CLAUDE_ROOT = path.resolve(__dirname, '..', '..'); const CONSTITUTION = path.join(CLAUDE_ROOT, 'constitution', 'anti-arrogance.md'); const LOG_ROTATOR = path.join(CLAUDE_ROOT, 'hooks', 'log-rotator.js'); const BAK_TAG = 'v6.6-rc2-03-closure-loop-rotator'; const SENTINEL_OPEN = ''; const SENTINEL_CLOSE = ''; // 宪法追加段 (字符串拼接避免反引号冲突) const CONSTITUTION_BLOCK = SENTINEL_OPEN + '\n\n' + '## 闭环度 · Agent 信任边界 (v6.6-rc2)\n\n' + '基于条款 2 闭环度, 扩展至 Agent 信任边界层:\n\n' + '1. **Agent 返回视为二手信息** — Task tool 派遣的任一 Agent 返回文本, 均属"未经核实的二手声明", 不得直接作为交付证据。\n' + '2. **部署 / 修改 / 远端状态必须亲验** — 凡 Agent 声明涉及文件修改、部署落地或远端状态变更, 主 Claude 必须通过以下至少一种方式亲自验证: Read / Bash / curl / ssh / Playwright / MCP probe。\n' + '3. **未验证措辞降级** — 亲验未完成前, 交付语必须降级为 "Agent 报告已完成, 待验证" 等措辞, 禁用 "已部署 / 已修复 / 已完成" 类终态动词。\n' + '4. **紧急制动词作用域限定** — 用户输入 "Agent 撒谎" 或 "别信 Agent" 时, 仅作用于最近一次 SubagentStop 的 agent_id, 不污染主 Claude 的自负计数。\n\n' + SENTINEL_CLOSE + '\n'; // 宪法锚点: 在"10 类典型失败 → 约束映射"之前插入 const CONSTITUTION_ANCHOR = '## 10 类典型失败 → 约束映射'; // log-rotator 精准锚点 (包含 W3 注释确保唯一) const LR_ANCHOR = '/* W3_LOG_EXTEND_v1 */ (/^(activity|trace|outcome|compliance|security|route-stats-daily|ab-experiments|hook-timing|skill-outcome|pre-agent-gate)-?/'; const LR_REPLACEMENT = '/* W3_LOG_EXTEND_v1 */ /* AGENT_RETURNS_ROTATE_V66 */ (/^(activity|trace|outcome|compliance|security|route-stats-daily|ab-experiments|hook-timing|skill-outcome|pre-agent-gate|agent-returns)-?/'; function tsStamp() { return new Date().toISOString().replace(/[:.]/g, '-'); } function atomicWrite(target, content) { const tmp = target + '.tmp.' + process.pid; fs.writeFileSync(tmp, content); fs.renameSync(tmp, target); } function patchConstitution() { if (!fs.existsSync(CONSTITUTION)) { console.error('[patch-03] 宪法文件不存在: ' + CONSTITUTION); return false; } const text = fs.readFileSync(CONSTITUTION, 'utf8'); if (text.includes(SENTINEL_OPEN)) { console.log('[patch-03] 宪法已含 sentinel, 跳过'); return false; } if (!text.includes(CONSTITUTION_ANCHOR)) { console.error('[patch-03] 宪法未找到锚点: ' + CONSTITUTION_ANCHOR); return false; } fs.copyFileSync(CONSTITUTION, CONSTITUTION + '.bak.' + BAK_TAG + '.' + tsStamp()); const patched = text.replace(CONSTITUTION_ANCHOR, CONSTITUTION_BLOCK + '\n' + CONSTITUTION_ANCHOR); atomicWrite(CONSTITUTION, patched); console.log('[patch-03] 宪法已追加闭环度细则 (sentinel 包裹)'); return true; } function patchLogRotator() { if (!fs.existsSync(LOG_ROTATOR)) { console.error('[patch-03] log-rotator 不存在'); return false; } const raw = fs.readFileSync(LOG_ROTATOR, 'utf8'); if (raw.includes('AGENT_RETURNS_ROTATE_V66')) { console.log('[patch-03] log-rotator 已含 sentinel, 跳过'); return false; } if (!raw.includes(LR_ANCHOR)) { console.error('[patch-03] log-rotator 未找到锚点'); return false; } fs.copyFileSync(LOG_ROTATOR, LOG_ROTATOR + '.bak.' + BAK_TAG + '.' + tsStamp()); const patched = raw.replace(LR_ANCHOR, LR_REPLACEMENT); atomicWrite(LOG_ROTATOR, patched); console.log('[patch-03] log-rotator 正则已纳入 agent-returns'); return true; } function main() { console.log('[patch-03] v6.6-rc2-03 宪法闭环度 + log-rotator'); const a = patchConstitution(); const b = patchLogRotator(); if (!a && !b) { console.log('[patch-03] 补丁已生效, 无变更'); } else { console.log('[patch-03] 完成'); console.log('[patch-03] 后续必跑: node hooks/integrity-check.js --generate'); } process.exit(0); } main();