#!/usr/bin/env node /** * 宪法作用域装配索引 — 2026-04-25 P0-1 * * 创建两个索引文件 (constitution/): * 1. AI-CONSTITUTION-CORE.md — 通用核心, 所有环境加载 * 2. AI-CONSTITUTION-PRODUCT.md — 产品专用, 仅 Bookworm Web Service * * 设计原则: * - 索引文件仅含: 装配说明 + 章节列表 + 激活条件 + 指向原文的查阅指引 * - 不复制正文, 避免多源漂移 (single source of truth = AI-CONSTITUTION.md) * - 幂等: 若目标文件存在且含 sentinel 则跳过 */ 'use strict'; const fs = require('fs'); const path = require('path'); const CONST_DIR = path.join(__dirname, '..', '..', 'constitution'); const CORE_PATH = path.join(CONST_DIR, 'AI-CONSTITUTION-CORE.md'); const PRODUCT_PATH = path.join(CONST_DIR, 'AI-CONSTITUTION-PRODUCT.md'); const CORE_SENTINEL = '[V14_CORE_INDEX]'; const PRODUCT_SENTINEL = '[V14_PRODUCT_INDEX]'; const CORE_CONTENT = `# AI Constitution — Core 通用核心 ${CORE_SENTINEL} > 本文件是 Bookworm AI 宪法的**通用核心装配索引**。所有环境常驻加载,跨产品通用。 ## 装配范围 适用于**所有 Bookworm Smart Assistant 环境**(管理员本机 \`.claude/\` / Portable 发行版 / Web Service 产品仓库)。 ## 包含章节 | 章 | 标题 | 核心价值 | |---|------|---------| | 第一章 | 身份与边界 (**1.3 安全红线** 重点) | NEVER 系列硬红线 | | 第二章 | 代码交付标准 (2.1 自审 + 2.3 影响声明) | 每次代码交付的基线 | | 第四章 | 安全编码规范 (4.2 输入校验 + **4.5 API Key 多模型 fallback**) | 防注入 / 防凭证误判 | | 第九章 | 跨 AI 一致性 (9.1 行为基线 + 9.3 优先级) | 多 AI 协作的统一语言 | | 第十一章 | 反腐败防护 (11.1 禁止模式 + 11.3 双重审查 + 11.5 回滚协议) | 防 AI 注入恶意代码 | | 第十二章 | 语义变更审计 (12.1 SEMANTIC DIFF + 12.2 不可静默修改) | 修改透明化 | | 第十三章 | 触发必调用 (MUST_INVOKE_SKILL + 交付质量底线) | 专业性 / 零容忍 | | 第十五章 | 红队差值硬指标 (差值 ≤ 10 才能发布) | 系统性盲区防御 | | 第十六章 | Git 工作流安全 (v1.4 新增) | 防 secrets 泄漏 / reset 事故 | ## 激活条件 - **无条件激活** — 所有 AI 对话开始即生效 - 与"全局宪章" (\`~/.claude/CLAUDE.md\` 交付质量宪章) 并列生效, 互补 ## 查阅指引 完整条款原文见 \`AI-CONSTITUTION.md\`。本文件仅作为**作用域装配索引**,不复制正文以避免多源漂移。 Hook 实施: - 2.1 自审提醒通过 \`hooks/review-report-checker.js\` + \`post-edit-dispatcher.js\` 注入实现 - 11.1 反腐败检测通过 \`hooks/constitution-guard.js\` 实现 - 15 红队差值尚需人工在 release 时触发 (尚未自动化) ## 版本 与主宪法同步: v1.4 (2026-04-25) --- *索引维护: 新增/删除通用章节时同步更新本文件。若发生漂移,以 \`AI-CONSTITUTION.md\` 为准。* `; const PRODUCT_CONTENT = `# AI Constitution — Product (Bookworm Web Service) ${PRODUCT_SENTINEL} > 本文件是 Bookworm AI 宪法的**产品专用装配索引**。仅当 AI 在 Bookworm Web Service 产品仓库工作时加载。 ## 装配范围 **不适用于**: - 管理员本机 \`.claude/\` 环境 (仅改智能助手基础设施, 不碰产品代码) - Bookworm Portable 发行版 (用户侧安装, 不改产品) - 其他任意非 Bookworm Web Service 仓库 **仅适用于**: Bookworm Web Service 产品源码仓库 (含 \`server.js\` + \`src/\` + \`public/index.html\` + \`deploy/\`) ## 包含章节 | 章 | 标题 | 为何产品专用 | |---|------|---------| | 第三章 | API 契约守护 (67 端点清单) | 绑定具体 REST API, 非产品环境无意义 | | 第五章 | 上下文记忆与会话连续性 (\`git log\` / \`server.js\` 行数) | 协议针对产品 git 仓库 | | 第六章 | 模块职责与架构规范 (\`src/auth.js\` 等文件矩阵) | 文件矩阵绑定产品目录 | | 第七章 | 测试规范 (\`test/run.js\` 零依赖框架) | 测试框架是产品内置 | | 第八章 | Git 提交格式 (\`AI-Provider:\` / \`Review-Status:\` 字段) | 产品仓库规范, 非普适 | | 第十四章 | NDA 技术保密 (Portable 发行版用户) | 仅 Portable 生效 | ## 激活条件 **自动激活** (满足任一): 1. 工作目录下存在 \`server.js\` (L1-10 匹配 \`const http = require('http')\` 原生 HTTP 服务) 2. 工作目录下 \`package.json\` 含 \`"name": "bookworm-web-service"\` 3. 工作目录根目录存在 \`.bookworm-product\` 标记文件 (空文件即可) 4. 工作目录路径包含 \`bookworm-web-service/\` 或 \`bookworm-portable/\` 片段 **未激活**: 视这些章节为空章, 不做任何提醒/检测。 ## 查阅指引 完整条款原文见 \`AI-CONSTITUTION.md\`。本文件仅作为**作用域装配索引**。 ## 空转抑制说明 10 天宪法真实作用评估 (2026-04-15 ~ 2026-04-25) 发现: - 第 3/5/6/7/8 章在管理员本机环境**整整 10 天 0 次触发** - 空转成本: 占据 AI context、稀释宪法权威感 - 解决: 通过本装配索引让 AI 在非产品环境**主动跳过**这些章节 ## 版本 与主宪法同步: v1.4 (2026-04-25) --- *索引维护: 产品专用章节变更时同步更新本文件。激活条件调整需同步 \`scripts/patches/patch-constitution-assembly-index.js\`。* `; function detectEol(sample) { return process.platform === 'win32' ? '\r\n' : '\n'; } function toEol(text, eol) { return eol === '\r\n' ? text.replace(/\r?\n/g, '\r\n') : text.replace(/\r\n/g, '\n'); } function writeAtomic(target, content) { const tmp = target + '.tmp.' + process.pid; fs.writeFileSync(tmp, content); fs.renameSync(tmp, target); } function ensureIndexFile(filePath, content, sentinel, label) { if (fs.existsSync(filePath)) { const existing = fs.readFileSync(filePath, 'utf8'); if (existing.includes(sentinel)) { console.log('[assembly-index] ' + label + ' 跳过: 已存在 (sentinel 命中)'); return false; } const backup = filePath + '.bak.assembly_index.' + Date.now(); fs.writeFileSync(backup, existing); console.log('[assembly-index] ' + label + ' 备份旧版: ' + path.basename(backup)); } const eol = detectEol(); writeAtomic(filePath, toEol(content, eol)); console.log('[assembly-index] ✓ ' + label + ' 写入完成 (EOL: ' + (eol === '\r\n' ? 'CRLF' : 'LF') + ')'); return true; } function main() { if (!fs.existsSync(CONST_DIR)) { console.error('[assembly-index] constitution/ 目录不存在: ' + CONST_DIR); process.exit(1); } console.log('[assembly-index] 启动 (P0-1 作用域拆分)'); let changed = 0; if (ensureIndexFile(CORE_PATH, CORE_CONTENT, CORE_SENTINEL, 'CORE 索引')) changed++; if (ensureIndexFile(PRODUCT_PATH, PRODUCT_CONTENT, PRODUCT_SENTINEL, 'PRODUCT 索引')) changed++; console.log('[assembly-index] 完成: ' + changed + ' / 2 文件写入'); console.log('[assembly-index] 主宪法 AI-CONSTITUTION.md 标题区已指向这两个索引 (v1.4 作用域说明)'); } try { main(); } catch (e) { console.error('[assembly-index] 异常:', e.message); console.error(e.stack); process.exit(99); }