- 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)
178 lines
7.1 KiB
JavaScript
178 lines
7.1 KiB
JavaScript
#!/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);
|
|
}
|