@mcgrapeng/ccg 3.1.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,206 @@
1
+ # CCG 能力全集(Capabilities)
2
+
3
+ > 本文档基于源码实际行为整理(非宣传文案),覆盖 `ccg`、`ccg.sh`、`ccg-workflow.sh`、`ccg-multi-provider.sh`、`ccg-bailian-models.sh`、`ccg-bailian-integration.sh`、`bin/ccg.js`。
4
+ >
5
+ > 一句话定位:CCG 是 **多模型代码评审守护者 + 风险感知路由 + 评审记忆 + 4 阶段自动化工作流**(review → commit gate → AI merge → push analysis)的一体化 Git 工作流引擎。
6
+
7
+ 运行约束:**Bash 3.2+(macOS 默认)与 zsh 双兼容**;依赖 `git`、`curl`、`jq`;四家模型至少配置其一。
8
+
9
+ ---
10
+
11
+ ## 1. 入口与使用方式
12
+
13
+ | 入口 | 形态 | 用途 |
14
+ |---|---|---|
15
+ | `ccg <action>` | 独立 CLI(bash 包装器) | 四阶段工作流 |
16
+ | `source ccg.sh && ccg_xxx` | 函数库 | 直接调用任意公共函数 |
17
+ | `bash ccg.sh <subcmd>` | dispatch 守卫 | 命令行直跑单个函数 |
18
+ | `/ccg`(Claude Code) | Slash 命令 | 由 `ccg.md` 协议驱动 Claude 编排 |
19
+ | `npx @mcgrapeng/ccg <cmd>` | Node CLI(`bin/ccg.js`) | install / uninstall / doctor / about / version |
20
+ | `ccg-precommit.bat` | Windows/TortoiseSVN 钩子 | 提交前网关(git 场景) |
21
+
22
+ CLI 顶层动作(`ccg_workflow`):`review` · `commit` · `merge` · `push`(= `push-check`)· `config` · `models`。
23
+
24
+ ---
25
+
26
+ ## 2. 四阶段工作流(核心)
27
+
28
+ ### Stage 1 — `ccg review` 代码评审 / 分歧检测
29
+ - 流程:`ccg_init` → `ccg_diff_capture` → `ccg_risk_score` → 自动选 mode → **任意 2 个 provider 并行** → `ccg_synthesize`(Claude 综合)
30
+ - 三段分类输出:
31
+ - **AGREEMENT** — 两边都指出(信号低,降级展示)
32
+ - **DIVERGENCE** — 两边矛盾(★核心价值,需人裁决)
33
+ - **BLINDSPOT** — 一方漏报另一方抓到(最高信号)
34
+ - 裁决:`merge` / `fix-required` / `discuss`
35
+ - 落 ledger、持久化报告、写状态 `.git/ccg/last-review.json` 供 Stage 2 复用
36
+ - `CCG_REVIEW=off` 可整段关闭(review 变 no-op)
37
+ - 安全:prompt 注入防御、>200KB diff 警告、Ctrl+C 杀子进程、1/2 成功仍继续
38
+
39
+ ### Stage 2 — `ccg commit "msg"` 评审门禁提交(**0 次 LLM 调用**)
40
+ 1. 自动 `git add -A`(含**未跟踪文件**;`CCG_NO_AUTO_ADD=1` 关闭)
41
+ 2. 读状态文件,**校验暂存 diff 哈希 == 已评审哈希**(改了即拒绝;`CCG_COMMIT_FORCE=1` 绕过)
42
+ 3. 按裁决:`merge`=✅ / `discuss`=⚠️默认放行(`CCG_GATE_DISCUSS=block` 可拦)/ `fix-required`=❌阻断
43
+ 4. 提交后删状态文件(一次性消费)
44
+
45
+ | 失败场景 | 结果 |
46
+ |---|---|
47
+ | 无前置评审 | ❌ 提示先 `ccg review`(或 `CCG_REVIEW=off`) |
48
+ | diff 已变 | ❌ 哈希不匹配 |
49
+ | 绕过哈希 | `CCG_COMMIT_FORCE=1` |
50
+
51
+ ### Stage 3 — `ccg merge <target>` AI 冲突解决(核心竞争力)
52
+ - 安全前置:拒绝脏工作区 / 游离 HEAD / 进行中操作(rebase·merge·cherry-pick·revert·bisect)/ 远程分叉 / source==target
53
+ - fetch + 同步 target;**合并前备份 target** → `ccg-backup/<target>-<ts>-<pid>-<rand>`
54
+ - `git checkout target` → `git merge --no-commit --no-ff <source>`
55
+ - **冲突分类**(仅 `content` 交给 AI):
56
+
57
+ | 类型 | 处理 |
58
+ |---|---|
59
+ | content | AI 解决 |
60
+ | binary / submodule / symlink | 需人工 |
61
+ | delete_modify / both_deleted | 需人工 |
62
+ | added_one_side / both_added / unknown | 需人工 |
63
+
64
+ - **3 级 AI 兜底**:Bailian → Claude → Codex+Gemini 并行 → `NEEDS_HUMAN_DECISION`
65
+ - 解析 `<<<<<<< ======= >>>>>>>`(diff3 的 `|||||||` base 段丢弃)
66
+ - 产物校验:无 markdown 围栏、无残留冲突标记、非空、无 `NEEDS_HUMAN_DECISION`
67
+ - 原子写回:mktemp + mv,保留文件权限,拒绝穿透符号链接,跨文件系统回退 cp
68
+ - **绝不静默丢码**:主模型若产出非法内容 → 升级人工,而非偷换副模型答案
69
+ - 实时进度 `[3/12] file ... ✅ resolved`;`CCG_MERGE_MAX_CONFLICTS`(默认 50)防失控
70
+ - 任一冲突需人工 → 不提交,留 target 供审;成功后默认删备份(`CCG_MERGE_KEEP_BACKUP=1` 保留)
71
+ - 开关:`CCG_MERGE_DRY_RUN` / `CCG_MERGE_NO_AI` / `CCG_MERGE_NO_FETCH`
72
+
73
+ ### Stage 4 — `ccg push <remote> <branch>` 推送前图形化决策
74
+ - 检测上游 / 远程 URL / ahead·behind / 终端宽度自适应(70–100 列)
75
+ - 提交质量标记(✓ 规范 / ⚠ WIP·FIXME·非规范)
76
+ - 文件分类:💻 代码 / 🧪 测试 / 📖 文档 / ⚙️ 配置 / 📦 其他
77
+ - **敏感文件检测**:`.env` `*.pem` `*.key` `id_rsa*` `*credentials*` `secrets*`
78
+ - 风险评估 + 可视化进度条
79
+ - **5 项质量记分卡**:规范提交 · 代码配套测试 · 无敏感文件 · 与远程同步 · 风险可接受
80
+ - 推荐:🟢 READY / 🟡 CAUTION / 🔴 NOT RECOMMENDED
81
+ - 决策 `y/n/d(diff)/l(log)` → **同意后真正 `git push`**(首推自动 `-u`)
82
+
83
+ ### 一键交付 — `ccg_ship [target] [msg]`
84
+ staged → `ccg_autocommit`(评审通过才提交)→ `ccg_merge <target>`。
85
+
86
+ ---
87
+
88
+ ## 3. Provider × Mode 模型策略
89
+
90
+ ### 四家独立 Provider
91
+ | Provider | 通道 | 依赖 | 自定义端点 |
92
+ |---|---|---|---|
93
+ | `codex` | Codex CLI(OpenAI) | `codex` 二进制 | `CCG_CODEX_BASE_URL` / `OPENAI_BASE_URL` |
94
+ | `gemini` | Gemini CLI(Google) | `gemini` 二进制 + `GEMINI_API_KEY` | `CCG_GEMINI_BASE_URL` / `GEMINI_BASE_URL` |
95
+ | `claude` | Anthropic API 直连 | `ANTHROPIC_API_KEY` / `CLAUDE_API_KEY` | `CCG_CLAUDE_BASE_URL` / `ANTHROPIC_BASE_URL` |
96
+ | `bailian` | 阿里云百炼 API 直连 | `BAILIAN_API_KEY` | `CCG_BAILIAN_BASE_URL` |
97
+
98
+ > ⚠️ **claude 在 Stage 1 强制禁用**,专留给综合步骤做独立第三方视角。
99
+
100
+ ### 三档 Mode(按风险自动选,`CCG_MODE` 可强制)
101
+ | Mode | 触发 | codex | claude | gemini | bailian |
102
+ |---|---|---|---|---|---|
103
+ | `cost` | risk < 30 | deepseek-v4 | claude-haiku-4-5 | qwen-3.7 | kimi-k2.6 |
104
+ | `balanced` | 30–70 | gpt-5.4 | claude-sonnet-4-6 | gemini-2.5-flash | qwen-3.6 |
105
+ | `quality` | > 70 | gpt-5.5 | claude-opus-4-7 | gemini-3.5-flash | deepseek-v4 |
106
+
107
+ > 默认模型名为本项目设定,第三方代理若不支持会 4xx/5xx,用 `CCG_*_MODEL` 显式指定代理实际支持的型号。
108
+
109
+ ### `CCG_PROVIDERS` 语法(Stage 1,最多 2 路并行)
110
+ ```bash
111
+ CCG_PROVIDERS="codex gemini" # 默认
112
+ CCG_PROVIDERS="bailian:qwen-3.7 bailian:deepseek-v4" # 同 provider 两个模型
113
+ CCG_PROVIDERS="codex:gpt-5.5 gemini:gemini-3.5-flash" # 显式模型
114
+ # claude 会被拒绝
115
+ ```
116
+
117
+ ### 百炼模型注册表(15 个,`ccg models` 可查)
118
+ qwen-3.7 / 3.6 / 3.6-plus / 3.5-sonnet / 3.5-haiku · deepseek-v4 / -lite · kimi-k2.6 / -lite · glm-5.1 / -lite · mimo-v2.5-pro / v2.5 · minimax-m2 / minimax-m2-lite(各含输入·输出价与档位)。
119
+
120
+ ---
121
+
122
+ ## 4. 基础设施 7 层(每层独立可用)
123
+
124
+ | 层 | 能力 | 关键实现 |
125
+ |---|---|---|
126
+ | **L1 安全 CLI 调度** | 超时 / stdin 保护 / 脱敏 / 清理安全 | 可移植 `timeout`(无则纯 bash 轮询);7+ 类密钥脱敏;Ctrl+C 杀子进程树;mktemp 700 工作区 + 24h 孤儿清扫 |
127
+ | **L2 内容寻址缓存** | 同 prompt 不重复付费(省 ~90%) | SHA-256(prompt+model)键,24h TTL,原子写,失败不入缓存,权限 600 |
128
+ | **L3 智能 diff 抓取** | 提交后也能抓到改动 | 4 级回退 worktree(含未跟踪)→ staged → upstream → origin-head,输出 `CCG_DIFF_SOURCE` |
129
+ | **L4 用量与成本遥测** | 按月 / 按模型看花费 | tab 分隔 usage.log;`ccg_usage`;字符数→token 估算(±15%) |
130
+ | **L5 风险感知路由** | 自动选档,纯规则可解释可改 | 见下方权重表(纯规则引擎;可选启用 LLM: `CCG_RISK_LLM=1`) |
131
+ | **L6 评审账本(双向)** | "上次模型对这文件怎么判的" | append-only JSONL;`ccg_ledger_query`;`ccg_ledger_context` 注入历史;超 10000 行轮转 |
132
+ | **L7 分歧检测(综合)** | 单模型看不到自己盲区 | 同 prompt 双投喂 → Claude 综合;兜底链 Claude→codex→bailian→gemini |
133
+
134
+ ### L5 风险打分规则(纯规则引擎)
135
+ - **路径**:auth+35 · payment+40 · migration+30 · crypto+30 · security+25 · infra+20 · ci+15;纯文档 −40
136
+ - **内容**:sql_interp+30 · shell_exec+25 · privilege+25 · fs_delete+20 · hardcoded_host+5 · todo_marker+5
137
+ - **规模**:>600 行 +25 / >300 +15 / >100 +5;文件数 >8 +10
138
+ - 阈值:<30 cost · 30-70 balanced · >70 quality
139
+
140
+ ---
141
+
142
+ ## 5. 提交门禁与 Git 钩子(另一条提交路径)
143
+
144
+ - **`ccg_precommit_gate`** — 跑评审并以退出码门禁(0 放行 / 1 阻断 / 2 错误);带 **per-call nonce 哨兵防 prompt 注入**(diff 内伪造的 `VERDICT: merge` 无效);**失败闭合(fail-closed)**;`CCG_GATE_OFFLINE=1` 跳过
145
+ - **`ccg_autocommit`** — **仅评审已暂存内容**(默认安全,防误提 `.env`/构建产物);评审期间索引被改则拒绝;`CCG_AUTOCOMMIT_ALL=1` 才 add -A;`CCG_AUTOCOMMIT_DRY_RUN=1` 演练
146
+ - **`ccg_install_hook` / `ccg_uninstall_hook`** — 安装/卸载 git `pre-commit` 钩子:链式保留已有钩子、备份原钩子、honor `core.hooksPath`(husky/lefthook)、原子写入 + 失败回滚、zsh 路径自省
147
+
148
+ ---
149
+
150
+ ## 6. 配置环境变量(全量)
151
+
152
+ **总开关 / 模式**:`CCG_MODE` · `CCG_REVIEW` · `CCG_PROVIDERS`
153
+ **模型覆盖**:`CCG_CODEX_MODEL` · `CCG_CLAUDE_MODEL` · `CCG_GEMINI_MODEL` · `CCG_BAILIAN_MODEL`
154
+ **密钥**:`BAILIAN_API_KEY` · `ANTHROPIC_API_KEY`/`CLAUDE_API_KEY` · `GEMINI_API_KEY`
155
+ **端点代理**:`CCG_CODEX_BASE_URL`/`OPENAI_BASE_URL` · `CCG_CLAUDE_BASE_URL`/`ANTHROPIC_BASE_URL` · `CCG_GEMINI_BASE_URL`/`GEMINI_BASE_URL` · `CCG_BAILIAN_BASE_URL`
156
+ **超时 / 参数**:`CCG_CODEX_TIMEOUT`(240)· `CCG_GEMINI_TIMEOUT`(120)· `CCG_BAILIAN_TIMEOUT`(120)· `CCG_BAILIAN_TEMP`(0.7)· `CCG_BAILIAN_MAX_TOKENS`(4096)· `CCG_BAILIAN_RETRIES`(3)· `CCG_CLAUDE_RETRIES`(3)
157
+ **门禁 / 提交**:`CCG_GATE_OFFLINE` · `CCG_GATE_DISCUSS` · `CCG_NO_AUTO_ADD` · `CCG_COMMIT_FORCE` · `CCG_AUTOCOMMIT_ALL` · `CCG_AUTOCOMMIT_DRY_RUN` · `CCG_DIFF_CACHED_ONLY`
158
+ **合并**:`CCG_MERGE_DRY_RUN` · `CCG_MERGE_NO_AI` · `CCG_MERGE_NO_FETCH` · `CCG_MERGE_MAX_CONFLICTS`(50)· `CCG_MERGE_KEEP_BACKUP`
159
+ **缓存 / 账本 / 报告**:`CCG_NO_CACHE` · `CCG_CACHE_TTL_HOURS`(24)· `CCG_CACHE_DIR` · `CCG_MAX_PROMPT_KB`(100)· `CCG_USAGE_LOG` · `CCG_LEDGER_LOG` · `CCG_LEDGER_MAX_LINES`(10000)· `CCG_NO_HISTORY` · `CCG_HISTORY_MAX`(3)· `CCG_NO_REPORT` · `CCG_REPORT_DIR` · `CCG_KEEP_ARTIFACTS`
160
+
161
+ ---
162
+
163
+ ## 7. 存储布局(XDG 规范)
164
+
165
+ | 路径 | 内容 |
166
+ |---|---|
167
+ | `$XDG_DATA_HOME/ccg/usage.log` | 用量 + 成本日志 |
168
+ | `$XDG_DATA_HOME/ccg/ledger.jsonl` | 逐次评审 JSONL 账本 |
169
+ | `$XDG_CACHE_HOME/ccg/cache/` | prompt 哈希 → 结果缓存(24h) |
170
+ | `$XDG_CONFIG_HOME/ccg/` | 用户配置 |
171
+ | `<repo>/.git/ccg/last-review.json` | Stage 1→2 复用状态 |
172
+ | `<repo>/.ccg/reports/<sha>_<ts>.md` | 持久化评审报告(自带 `.gitignore`) |
173
+
174
+ 旧 `~/.ccg/*` 首次运行自动迁移到 XDG 路径(非破坏式)。
175
+
176
+ ---
177
+
178
+ ## 8. 安全保证
179
+
180
+ - **密钥脱敏**:stderr / ledger / 报告(sk- · AIza · Bearer · JWT · ghp_ · AKIA · Slack · URL query)
181
+ - **prompt 注入防御**:不可信内容标记 + 每次调用唯一 nonce 哨兵(评审网关、冲突解决双侧标记)
182
+ - **合并安全**:先备份分支、绝不静默丢码、产物校验、原子写、拒穿符号链接、保留权限
183
+ - **门禁安全**:fail-closed;哈希门禁保证"评审什么 = 提交什么"
184
+ - **清理安全**:路径遍历防护(仅删绝对路径、basename 为 `ccg.*`、非符号链接)
185
+ - **prompt 大小硬限**:默认 100KB,防止把整个仓库塞进 prompt
186
+
187
+ ---
188
+
189
+ ## 9. 公共函数 API 速查
190
+
191
+ **初始化 / 探测**:`ccg_init` · `ccg_preflight`
192
+ **Diff / 风险**:`ccg_diff_capture <out>` · `ccg_risk_score <diff>`
193
+ **Provider 调用**:`ccg_codex` · `ccg_gemini` · `ccg_bailian` · `ccg_claude` · `ccg_bailian_stream`(均缓存感知、用量记账)
194
+ **综合 / 成本 / 用量**:`ccg_synthesize <a> <b> <out>` · `ccg_actual <prompt> <result> <provider>` · `ccg_usage [--this-month|--all|--since=]`
195
+ **账本 / 报告 / 清理**:`ccg_ledger_record` · `ccg_ledger_query [path]` · `ccg_ledger_context <diff>` · `ccg_persist_report <workdir>` · `ccg_cleanup <dir>`
196
+ **工作流**:`ccg_review` · `ccg_commit` · `ccg_merge` · `ccg_push_check` · `ccg_ship`
197
+ **门禁 / 钩子**:`ccg_precommit_gate` · `ccg_autocommit` · `ccg_install_hook` · `ccg_uninstall_hook`
198
+ **多 provider / 百炼辅助**:`ccg_with_providers`(ccg_review 轻量版)· `ccg_with_bailian` · `ccg_compare_models` · `ccg_benchmark` · `ccg_list_models` · `ccg_show_config`
199
+
200
+ ---
201
+
202
+ ## 10. 已知边界
203
+
204
+ - **SVN**:`_ccg_vcs_*` 抽象层目前仅支持 git;`bin/ccg-precommit.bat`(TortoiseSVN)调用的是 git-only 网关,SVN 工作副本下会判定"非 git 仓库"。SVN diff 支持属待补功能。
205
+ - **价格估算**:基于字符数 / 3.0 的启发式,±15%;部分默认模型为本项目设定的型号,价格为按档位的估算,正式费率发布后需更新 `_ccg_price`。
206
+ - **Codex 沙箱**:`codex exec` 在沙箱运行,不修改本地文件。
@@ -0,0 +1,252 @@
1
+ # Changelog
2
+
3
+ All notable changes to /ccg.
4
+
5
+ ## [4.0.0] — 2026-05-31
6
+
7
+ Major repositioning: from "multi-model divergence detector" to **"Code Change Guardian"** — a complete 4-stage Git workflow automation engine. Introduces `ccg-workflow.sh` orchestration and formal Stage 2/3/4 protocols.
8
+
9
+ ### Identity Shift
10
+ **Before (v3):** "Surface where Codex and Gemini disagree — that's your decision point."
11
+ **After (v4):** "Two independent AI model families guard every code change across four stages: Review synthesis → Deterministic commit gate → AI-assisted merge → Pre-push quality analysis."
12
+
13
+ ### Changed — Stage 1 Model Routing (Bailian-first)
14
+ - **Default Stage 1 reviewers are now two DIFFERENT-vendor Bailian models** (vendors: `qwen / glm / mimo / deepseek / kimi / minimax`), not `codex gemini`.
15
+ - `cost` → `qwen-3.5-haiku` + `deepseek-v4-lite`; `balanced` → `qwen-3.6` + `deepseek-v4`.
16
+ - **`codex` / `gemini` / `claude` are enabled only in `quality` mode**, where Stage 1 picks any 2 of the three and the leftover becomes the synthesizer (default `claude`). Risk auto-routing escalates high-risk diffs into quality.
17
+ - New different-vendor guard: same-vendor Stage 1 pairs are rejected (override `CCG_ALLOW_SAME_VENDOR=1`).
18
+ - Added **MiniMax** to the registry/pricing (`minimax-m2`, `minimax-m2-lite`) — completes the 6-vendor set.
19
+ - New env knobs: `CCG_PROVIDERS` (mode-aware default), `CCG_ALLOW_SAME_VENDOR`, `CCG_SYNTH_PROVIDER`, `CCG_RISK_LLM`.
20
+
21
+ ### Fixed
22
+ - **Ledger was recording empty rows**: `ccg_review` / `ccg_with_providers` / `ccg_with_bailian` passed `$(pwd)` instead of the workdir to `ccg_ledger_record`, so `files`/`paths`/`synthesis` were always blank. Now pass `$CCG_DIR`.
23
+ - **L6 history read-side was never wired**: `ccg_review` now calls `ccg_ledger_context` and splices prior-review context into the prompt.
24
+ - **Risk scoring is deterministic again**: the LLM path is now opt-in via `CCG_RISK_LLM=1` (was silently on whenever `BAILIAN_API_KEY` was set, contradicting the "pure rules, no LLM" contract).
25
+ - **`gemini` cost tier resolved to `qwen-3.7`** (and `codex` cost → `deepseek-v4`), causing the CLIs to be invoked with foreign model names. Now `gemini-2.5-flash-lite` / `gpt-5-mini`.
26
+ - Unified three divergent Bailian model resolvers; `_ccg_run_provider` no longer clobbers a user-set `CCG_BAILIAN_MODEL`.
27
+ - Robust Bailian API-error detection via `jq` (was a loose grep that false-matched review prose containing `"code"`).
28
+ - `_ccg_bailian_retry` no longer retries permanent errors (empty prompt / no key / missing jq).
29
+ - `ccg_review` now persists a durable report (`ccg_persist_report`), matching the gate path.
30
+ - `ccg_show_config` no longer crashes under zsh (`status` is read-only there) and no longer leaks `local`-in-loop values.
31
+ - Prompt-size warning aligned with the hard `CCG_MAX_PROMPT_KB` reject threshold.
32
+ - `package.json` version corrected to match this changelog; `bin/ccg.js` `which()` dead primary branch removed.
33
+
34
+ ### Fixed — V1 production-readiness audit (merge data-loss, security, gate)
35
+ - **CRITICAL — silent merge data loss**: `_ccg_apply_resolutions`/`_ccg_parse_conflicts` treated `=======`/`|||||||`/`>>>>>>>` as conflict markers *anywhere* in a file, so a marker-like line outside a conflict (e.g. a Markdown `=======` setext underline) was dropped and committed. Marker handling is now gated on conflict state.
36
+ - **CRITICAL — both sides dropped on unavailable resolution**: an empty/missing resolution wrote contentless markers (losing OURS *and* THEIRS). It now restores the original conflict block verbatim (markers + both sides) and flags needs-human.
37
+ - **HIGH — line-ending corruption**: merge apply force-converted CRLF→LF across the whole file; pass-through lines now preserve their original bytes.
38
+ - **HIGH — interior code stripped**: `grep -v '^CONFIDENCE:'` deleted *any* line starting with `CONFIDENCE:`; only a trailing AI-annotation line is now removed.
39
+ - **HIGH — wrong exit code**: `ccg_merge` returned 0 on a needs-human BLOCKED merge, so `ccg_ship`/CI treated it as success. It now returns 1.
40
+ - **Security — redaction gaps**: `AWS_SECRET_ACCESS_KEY=`, generic `*_KEY/*_SECRET/*_TOKEN=` env vars, `PASSWORD=`/`DB_PASS=`, Stripe `sk_live_`/`sk_test_` (underscore), and `user:pass@` URL userinfo are now masked; keyword-value threshold lowered 16→8 chars.
41
+ - **Gate bailian-first fallback**: `ccg_precommit_gate` no longer hard-blocks a Bailian-only user's high-risk commits — when premium CLIs are absent in quality mode it falls back to the Bailian pair. It also respects an explicit `CCG_MODE` instead of overwriting it.
42
+ - **API robustness**: non-numeric `CCG_BAILIAN_TEMP`/`*_MAX_TOKENS` no longer blank the `jq` payload (validated via `_ccg_num_or`); `ccg_claude` API-error detection uses `jq` (matching `ccg_bailian`).
43
+ - **Timeout**: the portable-timeout fallback now also kills child processes (`pkill -P`) so a timed-out codex/gemini CLI doesn't keep running.
44
+ - **Pre-push gate**: stopped blocking valid commits whose subject merely contains "todo"/"debug"; unattended auto-push now holds at HIGH risk (≥50) and won't push to an unconfigured remote; fixed `seq 1 0` bar-rendering glitch and an EXIT-trap leak on macOS; `bad_commits` no longer double-counts; unborn-branch handled cleanly.
45
+ - **Pricing**: `-lite`/`-plus` Bailian models (`deepseek-v4-lite`, `kimi-k2.6-lite`, `glm-5.1-lite`, `qwen-3.6-plus`) were mispriced because the general glob arm matched first; specific arms now precede the general arm.
46
+
47
+ ### Added — Stage 2: Auto Commit (Zero-LLM Gate)
48
+ - **`ccg_commit <message>`** — new protocol layer
49
+ - **🚫 No LLM calls** — reads Stage 1 synthesis from `.git/ccg/last-review.json`
50
+ - Deterministic hash-validation gate: diff modification detected → reject
51
+ - Verdict inheritance: `merge` → allow, `fix-required` → block, `discuss` → configurable
52
+ - Fail-closed: any desync → reject, output prior review findings
53
+ - `CCG_GATE_DISCUSS` env knob: default allow, set to `block` to upgrade to stricter gate
54
+
55
+ ### Added — Stage 3: AI Merge (Conflict Resolution)
56
+ - **`ccg_merge <target>`** — formalized multi-provider conflict resolution
57
+ - Bailian is primary resolver; Codex+Gemini fallback if Bailian fails
58
+ - Conflict classification: only `content`-type conflicts enter AI; others defer to human
59
+ - Backup branch created automatically (`ccg-backup/<target>-<timestamp>`) for safe rollback
60
+ - Per-conflict decision: AI-resolved vs `NEEDS_HUMAN_DECISION` (stays in merge state for manual review)
61
+
62
+ ### Added — Stage 4: Push Analysis (Pre-push Gate)
63
+ - **`ccg_push_check origin main`** — new protocol layer (invoked before `git push`)
64
+ - Graphical quality scorecard: files-changed, risk distribution, CI checks, merge-conflict history
65
+ - Verdict: safe-to-push / hold / escalate-to-human
66
+ - Caches analysis per (commit, target) pair; bypass with `--no-cache`
67
+
68
+ ### Added — `ccg-workflow.sh` Orchestration Engine
69
+ - Central dispatch for all 4 stages: `ccg_review` (L1) → `ccg_commit` (L2) → `ccg_merge` (L3) → `ccg_push_check` (L4)
70
+ - ~36K LOC: durable patterns, error recovery, multi-shell compatibility
71
+ - New public functions: `ccg_workflow <stage> <args>`
72
+ - Backward-compatible with v3 single-stage usage (naked `/ccg` still works)
73
+
74
+ ### Documentation
75
+ - `ccg.md` (slash command protocol) expanded with complete Stage 2/3/4 execution protocols
76
+ - `docs/ARCHITECTURE.md` — new §3a "4-Stage Workflow Architecture" section, updated file map to include `ccg-workflow.sh`
77
+ - `docs/README.md` (English) — updated identity positioning, complete 4-stage walkthrough
78
+ - All 3 language mirrors (`zh-CN`, `ja`, `ko`) — synced with new positioning and full Stage 2-4 descriptions
79
+ - `docs/CAPABILITIES.md` — updated opening to reflect guardian positioning
80
+
81
+ ### Compatibility
82
+ - Full backward compatibility with v3.x single-stage usage
83
+ - New stages are opt-in (user can still call `/ccg review` without touching commit/merge/push stages)
84
+ - Stage 2 (commit gate) can be disabled via `CCG_GATE_OFFLINE=1`
85
+ - Stage 3 (merge) can be dry-run via `CCG_MERGE_DRY_RUN=1`
86
+
87
+ ### Tests
88
+ - 20 new test cases covering all 4 stages + integration scenarios
89
+ - Total: 141 tests, all passing, ~45s runtime
90
+ - E2E workflow test: review → fix → commit → merge → push-check in single session
91
+
92
+ ## [3.2.0] — 2026-05-24
93
+
94
+ Closes the L6 loop: the ledger goes from write-only to bidirectional. Each `/ccg` now reads prior reviews on the touched files and injects them into the next prompt — recurring patterns and unresolved `fix-required` items no longer evaporate between sessions. 121-test regression (+10 new); safe drop-in upgrade from 3.1.0.
95
+
96
+ ### Added — Ledger consumer (closes the moat loop)
97
+ - **`ccg_ledger_context <diff_file>`** — new public helper. Extracts touched paths from the diff, greps the ledger for JSON-quoted `"<path>"` matches (fixed-string, so `src/foo.ts` won't false-match `src/foobar.ts`), dedups, takes the last `CCG_HISTORY_MAX` (default 3) most-recent entries, and writes them as a structured Markdown block to `<workdir>/history.txt` for prompt embedding. Pure shell (grep + sed) — no extra LLM call, millisecond-level overhead.
98
+ - **`ccg.md` step 2.5** — new protocol step between `ccg_diff_capture` (L3) and `ccg_risk_score` (L5). Claude embeds `history.txt` into both Codex and Gemini prompts before the diff, so both reviewers see "what we already argued about on these files" as prior context.
99
+ - **New env knobs**:
100
+ - `CCG_NO_HISTORY=1` — disable consumer (useful for "single-perspective baseline" reviews or debugging).
101
+ - `CCG_HISTORY_MAX=<n>` — cap injected entries (default 3; larger N inflates prompt size).
102
+ - **Dispatch subcommand** `bash ccg.sh ledger_context <diff_file>` for standalone shell use.
103
+ - **Status sentinels** parallel to existing helpers:
104
+ - `CCG_HISTORY_OK=<n>_matches_<max>_max` + `CCG_HISTORY_FILE=<path>`
105
+ - `CCG_HISTORY_NONE=0_matches` (ledger exists but no path overlap)
106
+ - `CCG_HISTORY_SKIPPED=<disabled|no-diff|no-ledger|no-paths-in-diff>`
107
+ - `CCG_HISTORY_FAIL=<reason>`
108
+
109
+ ### Fixed — cross-shell `local var` footgun (zsh)
110
+ - **Critical**: zsh treats `local var` (without `=`) as a *print* operation — it dumps the variable's current value to stdout. Declaring locals *inside* a loop body silently leaked iteration N-1's values into output files on machines where the user's default shell is zsh (i.e., when Claude Code's Bash tool inherits zsh as the underlying shell).
111
+ - Discovered during smoke-testing of `ccg_ledger_context`: iteration 2's `local ts sha mode ...` printed iteration 1's values into the rendered `history.txt`.
112
+ - Fix: hoist all loop-mutated locals once outside the while loop. Regression locked in by test 15.9 ("history.txt contains NO bash/zsh debug-leak lines").
113
+ - Architecture decision table updated with the rule: **inside loop bodies, `local var=` (with `=`) is mandatory** — bash treats `local var` and `local var=` identically, but zsh does not.
114
+
115
+ ### Documentation
116
+ - `docs/ARCHITECTURE.md` — new "L6 consumer" subsection in §3 covering algorithm, value proposition, the zsh footgun, and knobs. Data-flow diagram (§4) updated to include the new step. Design-decision table (§7) gains a row about `local var=`. Moat section (§9) reframed: L6 = ledger + consumer (the consumer is what compounds the data within a session).
117
+ - 4-language sync: `docs/ARCHITECTURE.{zh-CN,ja,ko}.md` mirror all of the above.
118
+ - README.md "Why ccg" §3 (and all 3 mirrors) updated to mention the auto-injection behavior.
119
+ - `ccg.md` configuration table gains `CCG_NO_HISTORY` + `CCG_HISTORY_MAX` rows; troubleshooting table gains rows for `CCG_HISTORY_SKIPPED=no-ledger` and `CCG_HISTORY_NONE=0_matches`.
120
+
121
+ ### Tests
122
+ - 10 new test cases (15.1 - 15.10):
123
+ - Skip paths (disabled / no-ledger / no-diff / no-paths-in-diff)
124
+ - NONE return on path-mismatch
125
+ - History file write + content correctness (ts/sha/mode for matched entries only)
126
+ - `CCG_HISTORY_MAX` enforcement
127
+ - **15.9 zsh regression guard** — asserts `history.txt` contains no bare `ts=` / `sha=` / `synth=` lines at column 1 (would re-appear if a future contributor moves `local` declarations back inside the loop)
128
+ - Dispatch subcommand exposed via `bash ccg.sh ledger_context`
129
+ - Suite total: 111 → 121, all passing. Runtime ~32s (unchanged).
130
+
131
+ ### Compatibility
132
+ - Drop-in safe from 3.1.0. New behavior is enabled by default but degrades to a no-op when:
133
+ - Ledger doesn't exist yet (first runs)
134
+ - Current diff touches files no prior review covers
135
+ - User sets `CCG_NO_HISTORY=1`
136
+ - No changes to existing function signatures. No changes to ledger record format (the consumer reads what `ccg_ledger_record` already writes).
137
+
138
+ ## [3.1.0] — 2026-05-23
139
+
140
+ Documentation and discoverability release. No core behavior changes; safe drop-in upgrade from 3.0.0.
141
+
142
+ ### Added
143
+ - **`ccg about` subcommand** — 7-layer capability probe. Shows what ccg can do in *this* environment (not what the README claims), with green/yellow/red status per layer, environment readiness checks (Codex CLI / Gemini CLI / GEMINI_API_KEY / git / slash command installation), XDG storage state (ledger entries, usage entries, cache size), and a quick-reference command palette.
144
+ - Aliases: `ccg capabilities`, `ccg caps`
145
+ - Use case: "I'm a new user / contributor — what is ccg actually doing on my machine right now?"
146
+ - **`docs/ARCHITECTURE.md`** — 387-line engineering reference for contributors and integrators. Documents the 7-layer architecture (L1 Safe CLI scheduling → L7 Divergence synthesis), each layer's purpose / problem / solution / "what breaks if you remove it", end-to-end data flow, extension points (signed contract for new risk rules / new LLM providers / new storage paths / pricing customization), invariants enforced by the test suite, and load-bearing design decisions that look weird at first glance.
147
+ - **4-language ARCHITECTURE translations**: `docs/ARCHITECTURE.zh-CN.md`, `docs/ARCHITECTURE.ja.md`, `docs/ARCHITECTURE.ko.md`. Cross-linked from each language's README.
148
+
149
+ ### Changed
150
+ - **README fully rewritten** with a concrete bcrypt walkthrough — actual output (not placeholder mockups) showing how AGREEMENT / DIVERGENCE / BLINDSPOT sections render in practice. The example shows two real-world disagreement: should `bcrypt` be wrapped with `subtle.ConstantTimeCompare`? Claude synthesizes that Codex's recommendation would break the comparison entirely because bcrypt uses a fresh salt every call.
151
+ - **"When to use ccg" rewritten** — replaced the security-only framing (auth / payments / migrations / crypto) with judgment-difficulty framing. New trigger: *feeling*, not *domain*. Added cross-domain examples across social platforms, data/AI infra, frontend, API design, distributed systems, database, and security — emphasizing that divergence detection earns its cost on *any* change where two reasonable engineers might disagree.
152
+ - **README structure** restructured into three-part flow: What / Why-vs-alternatives / Install / Walkthrough — designed to answer "what does it do" and "what does the output mean" before diving into config.
153
+ - README v-prefix removed from H1 headings (no more "v3" branding in titles; version lives in CHANGELOG + npm).
154
+
155
+ ### Internal
156
+ - `PROMO.md` added to `.gitignore` (marketing copy file, not part of npm package).
157
+
158
+ ## [3.0.0] — 2026-05-23
159
+
160
+ Repositioning: from "multi-model review tool" to **"code divergence detector"**. Three structural pillars added; product opinion sharpened. 99-test regression (stable across 3 consecutive runs).
161
+
162
+ ### Identity shift
163
+ **Before (v2):** "Get multi-model second opinions, see consensus + disagreement + actions."
164
+ **After (v3):** "Surface where Codex and Gemini *disagree* — that's where you actually need to make a call. Agreement is low-signal; divergence is the gold."
165
+
166
+ This is a category change. v3 deliberately downgrades the AGREEMENT section (one-liners only) and elevates DIVERGENCE (full expansion + `NEEDS HUMAN DECISION` markers).
167
+
168
+ ### Added — Pillar 1: Divergence Engine
169
+ - Structured `[FINDING]…[/FINDING]` prompt protocol; both reviewers must conform
170
+ - Three-section synthesis output: `AGREEMENT (N) / DIVERGENCE (M) / BLINDSPOT (≤2)`
171
+ - `VERDICT` line: merge | fix-required | discuss
172
+ - `NEEDS HUMAN DECISION` is an explicit signal, not implied
173
+
174
+ ### Added — Pillar 2: Risk-Aware Routing
175
+ - `ccg_risk_score <diff_file>` — deterministic 0..100+ scoring
176
+ - Path signals: auth/payment/migration/crypto/security/infra/ci (+15..+40)
177
+ - Body signals: shell exec/SQL interp/fs delete/privilege ops (+5..+30)
178
+ - Size signals: lines and files-changed (+5..+25)
179
+ - Docs-only subtraction (-40)
180
+ - Auto mode selection: <20 cost, <60 balanced, ≥60 quality
181
+ - Manual `CCG_MODE=` override always wins
182
+ - Outputs reason string for full transparency: `auth+35 sql_interp+30 size>300+15`
183
+ - Pure rules, zero LLM cost, social-PR friendly
184
+
185
+ ### Added — Pillar 3: Review Ledger
186
+ - `ccg_ledger_record <workdir>` — append JSONL row to `~/.ccg/ledger.jsonl`
187
+ - Fields: ts, repo, branch, sha, mode, risk, files, lines, paths[], synthesis (redacted, ≤400 chars)
188
+ - `ccg_ledger_query [path-substring]` — search prior reviews
189
+ - `CCG_LEDGER_LOG` env override
190
+ - Synthesis excerpt runs through `_ccg_redact` before write (secret hygiene)
191
+
192
+ ### Fixed — diff capture deep gap
193
+ - Old behavior: `git diff HEAD` only → empty after commit
194
+ - New 4-level fallback: `worktree → staged → upstream:@{u}…HEAD → origin/HEAD…HEAD`
195
+ - Reports `CCG_DIFF_SOURCE=<level>` so caller knows what scope was captured
196
+ - Resolves "I committed and now /ccg sees nothing" footgun
197
+
198
+ ### Changed
199
+ - Default `CCG_MODE=auto` (was `balanced`); auto uses risk score
200
+ - `ccg_init` now also exposes `CCG_SYNTHESIS_FILE` and `CCG_RISK_FILE` paths
201
+ - Dispatch subcommands added: `risk_score`, `ledger_record`, `ledger_query`
202
+
203
+ ### Tests
204
+ - 13 new test cases (13.1 - 13.13) covering all three pillars + diff fallback
205
+ - All 99 tests pass; 31s runtime; stable across consecutive runs
206
+
207
+ ## [2.0.0] — 2026-05-23
208
+
209
+ Major refactor based on honest self-critique: drop low-value features, add high-leverage ones.
210
+ 86-test regression (stable across 10 consecutive runs).
211
+
212
+ ### Removed
213
+ - **Pre-execution cost estimate** (`ccg_estimate`). Estimating output tokens by assumption produced 3-5× wrong predictions, misleading users. Post-execution `ccg_actual` remains — it uses real byte counts.
214
+ - **Asymmetric prompt split** (codex=architecture, gemini=UX). It was pure intuition with no evidence. v2 sends the **same prompt to both providers** — training-data differences create natural diversity.
215
+ - `ccg_mode_resolve` public subcommand (resolution is now internal/silent)
216
+ - `CCG_USD_CNY_RATE`, `CCG_OUTPUT_TOKENS_ESTIMATE`, `CCG_TOKEN_CHARS_RATIO` knobs (no one tuned them)
217
+
218
+ ### Added
219
+ - **Auto `git diff` mode**: naked `/ccg` (no args) captures `git diff HEAD` and runs a pre-commit triangulated review. One-keystroke workflow.
220
+ - `ccg_diff_capture <out_file>` — captures `git diff HEAD`, falls back to `--cached`, returns `CCG_DIFF_OK/FAIL`
221
+ - **24h prompt-hash cache** keyed by SHA-256(model + prompt). Same prompt + same model → cached result, $0.00 cost. Iterating on the same code saves 90%+ on repeat calls.
222
+ - `CCG_CACHE_DIR` (default `~/.ccg/cache`) and `CCG_CACHE_TTL_HOURS` (default 24)
223
+ - `CCG_NO_CACHE=1` opt-out per-call
224
+ - **Usage log** at `~/.ccg/usage.log` (TSV: timestamp, provider, model, in_tokens, out_tokens, USD, cached). Only successful calls logged. Override path via `CCG_USAGE_LOG`.
225
+ - `ccg_usage [--this-month|--all|--since=YYYY-MM]` aggregates spend by provider with cache-hit count
226
+ - **Prompt size guard**: `CCG_MAX_PROMPT_KB=100` default. Hard reject prompts above this. Prevents the "I piped my whole repo and got a $5 bill" footgun.
227
+ - New dispatch subcommands: `diff_capture`, `usage`, `actual`
228
+
229
+ ### Fixed
230
+ - Test suite now isolates cache via `CCG_CACHE_DIR` (not `HOME`), so test runs no longer break codex/gemini auth lookup
231
+ - Mock-mode test helpers always set `CCG_NO_CACHE=1` so failure-mode tests can't be masked by an earlier success-mode cache entry
232
+
233
+ ## [1.0.0] — 2026-05-22
234
+
235
+ First production-ready release.
236
+
237
+ ### Added
238
+ - `CCG_MODE=cost|balanced|quality` for model selection
239
+ - `CCG_CODEX_MODEL`/`CCG_GEMINI_MODEL` explicit overrides
240
+ - `ccg_codex` passes `-m <model>` when set
241
+ - LICENSE (MIT), CHANGELOG, scripts/install.sh
242
+ - 86-test regression in `tests/test_ccg.sh`
243
+
244
+ ### Fixed
245
+ - **CRITICAL**: pure-bash timeout fallback lost stdin in async children. Real Codex/Gemini stdin delivery now works in all bash modes via explicit `<&0`.
246
+ - Timeout polling granularity: 1s → 0.1s + wall-clock deadline for sub-second responsiveness.
247
+ - Orphan sweep threshold: 60min → 1440min (24h).
248
+ - `eval`-safety for any printed shell-meta in mode descriptions.
249
+
250
+ ## [0.x] — pre-release
251
+
252
+ Initial two-file plugin (commands/ccg.md + commands/ccg.sh).