@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.
package/README.md CHANGED
@@ -1,220 +1,655 @@
1
- # ccg — Code Divergence Detector
1
+ # CCG — Code Change Guardian
2
2
 
3
- > A Claude Code slash command. Install once, type `/ccg` on a diff.
3
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
4
+ [![Bash](https://img.shields.io/badge/Shell-Bash%203.2%2B-green.svg)]()
5
+ [![Models](https://img.shields.io/badge/Models-25%2B-purple.svg)]()
4
6
 
5
- [![Tests](https://img.shields.io/badge/tests-99%20passing-brightgreen.svg)]()
6
- [![npm](https://img.shields.io/npm/v/@mcgrapeng/ccg.svg)](https://www.npmjs.com/package/@mcgrapeng/ccg)
7
- [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+ > **CCG (Code Change Guardian)** is a multi-model code review and Git workflow automation system.
8
+ > Two independent AI model families guard every change across **Review · Commit · Merge · Push** —
9
+ > divergence-aware review, risk-aware model routing, AI merge-conflict resolution, and a pre-push gate,
10
+ > from the working tree to the remote.
8
11
 
9
- **English** [简体中文](README.zh-CN.md) [日本語](README.ja.md) [한국어](README.ko.md) · [Architecture →](docs/ARCHITECTURE.md)
12
+ CCG runs two independent models in parallel on each diff and lets Claude synthesize their findings. When they **agree**, signal is low; when they **diverge**, that's where humans should focus. Beyond review it adds a zero-LLM commit gate, AI-powered merge-conflict resolution, and a graphical pre-push scorecard — with a JSONL ledger that makes every review reusable.
13
+
14
+ **Other languages**: [简体中文](docs/README.zh-CN.md) · [日本語](docs/README.ja.md) · [한국어](docs/README.ko.md)
10
15
 
11
16
  ---
12
17
 
13
- ## What is ccg
18
+ ## Table of Contents
14
19
 
15
- You're about to merge a change to `auth/login.go`. You want a sanity check. Today you have three options, all of them flawed:
20
+ - [Why CCG](#why-ccg)
21
+ - [Installation](#installation)
22
+ - [Quick Start](#quick-start)
23
+ - [The 4 Stages](#the-4-stages)
24
+ - [Model Strategy](#model-strategy)
25
+ - [Configuration](#configuration)
26
+ - [Architecture](#architecture)
27
+ - [Documentation](#documentation)
16
28
 
17
- - **Single-model review** (Copilot, Cursor `/review`, Aider) gives you **one perspective**. If Claude misses a timing attack, you miss it too.
18
- - **Multi-model gateways** (zen-mcp-server etc.) **average opinions**, hiding exactly the places where smart models disagreed — which is the only place you actually needed help.
19
- - **Manual cross-checking** is what you'd do if you had unlimited time. You don't.
29
+ ---
20
30
 
21
- ccg is a `/ccg` slash command for Claude Code that fixes all three. On any diff, it:
31
+ ## Why CCG
22
32
 
23
- 1. Sends the same prompt to **Codex (OpenAI)** and **Gemini (Google)** in parallel
24
- 2. Has **Claude** read both reports and surface **specifically where they disagree** — that's where human judgment is needed
25
- 3. Tracks cost, picks the cheapest model good enough for the risk level, and remembers past reviews
33
+ CCG guards the entire path from working tree to remote not just the review step. Each stage targets a specific pain point:
26
34
 
27
- **Think of it like:** asking two senior engineers from different teams to review the same PR, then having a tech lead synthesize: "they agree on these issues, they disagree on this one — you decide, and here's my read."
35
+ | Problem | CCG's Answer |
36
+ |---|---|
37
+ | Single-model review has blind spots | Two independent model families review in parallel — surface where they **disagree** |
38
+ | One-size-fits-all model wastes money / quality | Risk-aware auto-routing: cheap for low-risk, premium for critical |
39
+ | Merge conflicts are tedious and error-prone | **AI conflict resolution with Bailian as primary** — multiple safety guards, never silently drops code |
40
+ | Push decisions lack context | Stage 4 produces a **graphical quality scorecard** before push |
41
+ | Reviews aren't reusable | JSONL ledger captures every review, queryable by path |
28
42
 
29
- ## When to use ccg
43
+ ---
30
44
 
31
- The trigger isn't a *domain* — it's a *feeling*. Use ccg when, looking at your own diff, you catch yourself thinking:
45
+ ## Installation
32
46
 
33
- | Inner monologue | Use ccg? |
34
- |---|---|
35
- | "If I get this wrong, I'll get paged at 3am." | ✅ Yes |
36
- | "This is a judgment call — no obviously right answer." | ✅ Yes |
37
- | "I wish someone else would look at this first." | ✅ Yes |
38
- | "I just renamed a variable." | ❌ No |
39
- | "Docs-only change." | ❌ No |
40
- | "I want streaming chat with one model." | ❌ No (use the CLI directly) |
47
+ ```bash
48
+ # Clone & install
49
+ git clone https://github.com/your-org/ccg.git
50
+ cd ccg
51
+ ln -s "$(pwd)/ccg" /usr/local/bin/ccg
52
+
53
+ # Verify
54
+ ccg config
55
+ ccg models
56
+ ```
41
57
 
42
- **Examples across domains** — none of these are auth/crypto, all of them are real "two senior engineers would disagree" moments:
58
+ **Requirements:**
59
+ - `bash 3.2+`, `git`, `curl`, `jq`
60
+ - At least one of: `codex` CLI, `gemini` CLI, `ANTHROPIC_API_KEY`, or `BAILIAN_API_KEY`
43
61
 
44
- - **Social platforms** re-ranking the feed with a new engagement signal · comment-thread fan-out strategy · A/B test bucketing logic · anti-abuse rate-limit policy · graph-DB schema for follow relationships
45
- - **Data / AI infra** switching embedding model (do you re-index?) · changing chunking strategy · RAG retrieval scoring · prompt-injection defense layering
46
- - **Frontend** SSR vs ISR vs RSC for a new page · cache invalidation strategy · state-management refactor · accessibility trade-offs
47
- - **API design**cursor vs offset pagination · error response model · versioning approach · idempotency-key handling
48
- - **Distributed systems** timeout/retry policy · cache TTL vs event-driven invalidation · partition tolerance trade-off · leader-election semantics
49
- - **Database** — multi-step migration sequencing · index choice on a hot path · transaction isolation level · soft-delete vs hard-delete
50
- - **Security** — yes, auth / crypto / payments too — but just one of many domains
62
+ **Custom API endpoints (third-party proxies supported):**
63
+ - `CCG_CODEX_BASE_URL` / `OPENAI_BASE_URL`Codex / OpenAI proxy
64
+ - `CCG_CLAUDE_BASE_URL` / `ANTHROPIC_BASE_URL` Claude / Anthropic proxy
65
+ - `CCG_GEMINI_BASE_URL` / `GEMINI_BASE_URL` Gemini proxy
66
+ - `CCG_BAILIAN_BASE_URL`Bailian proxy
51
67
 
52
- **The pattern:** any change where a reasonable engineer might pick option A and another reasonable engineer might pick option B. That's when divergence detection earns its $0.04.
68
+ ---
69
+
70
+ ## Quick Start
71
+
72
+ ```bash
73
+ # 1. Review your current changes
74
+ ccg review
53
75
 
54
- ## Why ccg (vs everything else)
76
+ # 2. Auto-commit if review gate passes
77
+ ccg commit "feat: add user auth"
55
78
 
56
- **1. Disagreement is the signal, not the noise.**
57
- When Codex says "use `subtle.ConstantTimeCompare`" and Gemini says "bcrypt is already constant-time, that's cargo-cult", *that* is where you need to think. Other tools blend these into a vague "consider timing attacks". ccg shows you the conflict verbatim.
79
+ # 3. Merge with AI conflict resolution
80
+ ccg merge main
58
81
 
59
- **2. Cost telemetry built in.**
60
- Codex/Gemini CLIs don't tell you what you spent. ccg logs every call, picks the cheapest sufficient model automatically (risk-aware routing), and caches identical prompts for 24h. `ccg_usage --this-month` answers "how much have I spent so far?".
82
+ # 4. Pre-push graphical analysis & decision
83
+ ccg push origin main
61
84
 
62
- **3. A review history that survives across sessions.**
63
- "What did the model say about `src/auth.ts` two weeks ago?" — ccg's append-only ledger answers that. No stateless tool can.
85
+ # Helper commands
86
+ ccg config # Show current configuration
87
+ ccg models # List all available models
88
+ ```
64
89
 
65
- ## Install
90
+ ### Skip Review Mode
66
91
 
67
- Pick one:
92
+ For trivial changes (docs, typos) you can disable Stage 1 entirely:
68
93
 
69
94
  ```bash
70
- # npm (recommended)
71
- npx @mcgrapeng/ccg install
95
+ # Skip review — commit becomes the first stage
96
+ export CCG_REVIEW=off
97
+
98
+ ccg commit "docs: fix typo" # Auto git add + commits (no LLM)
99
+ ccg push origin main # Push still works
72
100
 
73
- # or curl one-liner, no Node
74
- curl -fsSL https://raw.githubusercontent.com/mcgrapeng/ccg/main/scripts/curl-install.sh | bash
101
+ # Re-enable later
102
+ unset CCG_REVIEW # or: export CCG_REVIEW=on
75
103
  ```
76
104
 
77
- Then install the AI CLIs once:
105
+ The `CCG_REVIEW` switch accepts: `on` (default) / `off` / `0` / `false` / `disabled`.
78
106
 
79
- ```bash
80
- npm i -g @openai/codex @google/gemini-cli
81
- echo 'export GEMINI_API_KEY="<your-key>"' >> ~/.zshenv
107
+ ---
108
+
109
+ ## Complete Workflow
110
+
111
+ ### Default Flow (Review enabled)
112
+
113
+ ```
114
+ ┌───────────────────────────────────────────────────────────────────────┐
115
+ │ Stage 1: ccg review 【3 LLM calls】 │
116
+ │ ───────────────────── │
117
+ │ 1. ccg_init → mktemp workdir + paths │
118
+ │ 2. ccg_diff_capture → 4-level fallback (worktree / staged / ...) │
119
+ │ 3. ccg_risk_score → Bailian LLM (fallback: rule engine) │
120
+ │ 4. Auto-pick CCG_MODE (cost/balanced/quality) by risk │
121
+ │ 5. Run any 2 providers in parallel (codex/gemini/bailian) │
122
+ │ 6. ccg_synthesize → Claude meta-review │
123
+ │ → CLASSIFICATION: AGREEMENT / DIVERGENCE / BLINDSPOT │
124
+ │ → VERDICT: merge / fix-required / discuss │
125
+ │ 7. Persist state to <repo>/.git/ccg/last-review.json │
126
+ └───────────────────────────────────────────────────────────────────────┘
127
+
128
+ ┌───────────────────────────────────────────────────────────────────────┐
129
+ │ Stage 2: ccg commit "msg" 【0 LLM calls】 │
130
+ │ ───────────────────────── │
131
+ │ 1. git add -A (auto-stage worktree; opt out via │
132
+ │ CCG_NO_AUTO_ADD=1) │
133
+ │ 2. Read last-review.json (refuses if missing) │
134
+ │ 3. Compare staged diff hash with reviewed hash │
135
+ │ → mismatch? refuse and ask user to re-run 'ccg review' │
136
+ │ 4. Apply verdict: │
137
+ │ • merge → ✅ commit │
138
+ │ • discuss → ⚠️ commit (or block if CCG_GATE_DISCUSS=block) │
139
+ │ • fix-required → ❌ block │
140
+ │ 5. git commit -m "msg" │
141
+ │ 6. Delete state file (one-shot) │
142
+ └───────────────────────────────────────────────────────────────────────┘
143
+
144
+ ┌───────────────────────────────────────────────────────────────────────┐
145
+ │ Stage 3: ccg merge <target> 【on-demand LLM】 │
146
+ │ ─────────────────────────── │
147
+ │ 1. Safety checks: clean tree, no detached HEAD, no mid-op │
148
+ │ 2. git fetch + sync local target with origin │
149
+ │ 3. Create backup branch (ccg-backup/<target>-<ts>-<pid>-<rand>) │
150
+ │ 4. git checkout target + git merge --no-commit feature │
151
+ │ 5. For each conflict file: │
152
+ │ a. classify (content / binary / submodule / symlink / ...) │
153
+ │ b. parse <<<<<<< >>>>>>> blocks │
154
+ │ c. AI resolution (Bailian → Claude → Codex+Gemini) │
155
+ │ d. validate (no markdown fences, no conflict markers, non-empty) │
156
+ │ e. atomic file rewrite (mktemp + mv, preserve perms) │
157
+ │ f. git add (only if resolved cleanly) │
158
+ │ 6. git commit (if all clean) OR leave uncommitted (if needs-human) │
159
+ │ 7. Real-time progress: [3/12] src/auth.js ... ✅ resolved │
160
+ └───────────────────────────────────────────────────────────────────────┘
161
+
162
+ ┌───────────────────────────────────────────────────────────────────────┐
163
+ │ Stage 4: ccg push <remote> <branch> 【1 LLM call】 │
164
+ │ ────────────────────────────────── │
165
+ │ 1. Detect upstream + remote URL │
166
+ │ 2. Compute commits ahead / behind │
167
+ │ 3. List commits with quality markers (✓ conventional / ⚠ WIP) │
168
+ │ 4. Categorize files (💻 code / 🧪 tests / 📖 docs / ⚙️ config) │
169
+ │ 5. Detect sensitive files (.env / *.pem / credentials / ...) │
170
+ │ 6. ccg_risk_score on the push diff (Bailian LLM) │
171
+ │ 7. Quality Scorecard (5 checks): │
172
+ │ • conventional commit messages │
173
+ │ • tests updated alongside code │
174
+ │ • no sensitive files │
175
+ │ • up to date with remote │
176
+ │ • risk level acceptable │
177
+ │ 8. Recommendation: 🟢 READY / 🟡 CAUTION / 🔴 NOT RECOMMENDED │
178
+ │ 9. Decision prompt: y/n/d (diff)/l (log) │
179
+ │ 10. git push (if y) │
180
+ └───────────────────────────────────────────────────────────────────────┘
82
181
  ```
83
182
 
84
- Verify:
183
+ ### Skip-Review Flow (`CCG_REVIEW=off`)
184
+
185
+ ```
186
+ ┌───────────────────────────────────────────────────────────────────────┐
187
+ │ Stage 1: ccg review 【0 LLM calls】│
188
+ │ → ℹ️ Review stage is DISABLED — no-op │
189
+ └───────────────────────────────────────────────────────────────────────┘
190
+
191
+ ┌───────────────────────────────────────────────────────────────────────┐
192
+ │ Stage 2: ccg commit "msg" 【0 LLM calls】│
193
+ │ → 1. git add -A │
194
+ │ → 2. ⚠️ Review stage DISABLED — committing without review │
195
+ │ → 3. git commit -m "msg" │
196
+ └───────────────────────────────────────────────────────────────────────┘
197
+
198
+ (Stage 3 / Stage 4 unchanged from default flow)
199
+ ```
200
+
201
+ ---
202
+
203
+ ---
85
204
 
205
+ ## The 4 Stages
206
+
207
+ CCG is built around four stages. Each has a specific purpose, model strategy, and safety guarantees.
208
+
209
+ ### Stage 1 — Code Review (`ccg review`)
210
+
211
+ **Purpose**: Identify bugs, security issues, and quality problems in your diff.
212
+
213
+ **Model strategy**:
214
+ - Runs **any 2 models in parallel** from different vendors
215
+ - **Default depends on mode**:
216
+ - `cost`/`balanced`: two different-vendor Bailian models (e.g., `qwen-3.5-haiku` + `deepseek-v4-lite`)
217
+ - `quality`: `codex + gemini` (CLI-based, independent)
218
+ - **🚫 Claude is STRICTLY FORBIDDEN in Stage 1** — it is reserved exclusively for the Synthesis step where it serves as the meta-reviewer with an independent perspective
219
+ - Models are selected by current `CCG_MODE` (see [Model Strategy](#model-strategy))
220
+
221
+ **`CCG_PROVIDERS` syntax** (Stage 1 only — max 2 parallel):
86
222
  ```bash
87
- npx @mcgrapeng/ccg doctor # check Codex / Gemini / API key
88
- npx @mcgrapeng/ccg about # 7-layer capability probe + runtime state
223
+ # quality mode default codex + gemini (CLI-based, independent)
224
+ CCG_PROVIDERS="codex gemini"
225
+
226
+ # Same provider, two different models — e.g., 2 Bailian models in parallel
227
+ CCG_PROVIDERS="bailian:qwen-3.7 bailian:deepseek-v4"
228
+
229
+ # Mix providers with explicit model overrides (quality mode only)
230
+ CCG_MODE=quality CCG_PROVIDERS="codex:gpt-5.5 gemini:gemini-3.5-flash"
231
+
232
+ # Cost optimization — all domestic models
233
+ CCG_PROVIDERS="bailian:kimi-k2.6 bailian:glm-5.1"
234
+
235
+ # ❌ DO NOT do this — claude is rejected and ccg review will return error
236
+ # CCG_PROVIDERS="claude codex"
89
237
  ```
90
238
 
91
- ## Try it a walkthrough
239
+ **Output**: Synthesis classified as one of:
240
+ - `AGREEMENT` — both reviewers flag same issues (high confidence)
241
+ - `DIVERGENCE` — reviewers contradict (needs human judgment)
242
+ - `BLINDSPOT` — one missed issues the other caught (highest signal)
243
+
244
+ **Pipeline**:
245
+ ```
246
+ git diff → risk scoring → mode selection
247
+ → parallel: [Codex review + Bailian review]
248
+ → synthesize → AGREEMENT | DIVERGENCE | BLINDSPOT
249
+ ```
92
250
 
93
- Say you just edited `auth/login.go`:
251
+ **Safety guarantees**:
252
+ - Prompt injection defense (untrusted-content markers, per-call nonce)
253
+ - Diff size warning (>200KB may exceed context)
254
+ - Cleanup trap (Ctrl+C kills child processes)
255
+ - Partial-failure handling (1/2 success → continue with warning)
94
256
 
95
- ```go
96
- // before // after
97
- func Login(user, pw string) bool { func Login(user, pw string) bool {
98
- u := lookupUser(user) u := lookupUser(user)
99
- - return u.Hash == sha256.Sum256([]byte(pw)) hashed, err := bcrypt.GenerateFromPassword([]byte(pw), 12)
100
- + if err != nil { return false }
101
- + return subtle.ConstantTimeCompare(u.Hash, hashed) == 1
257
+ ---
258
+
259
+ ### Stage 2 Auto Commit (`ccg commit`)
260
+
261
+ **Purpose**: Enforce that only reviewed code reaches git history — **without any extra LLM calls**.
262
+
263
+ **Model strategy**: 🚫 **No LLM calls in Stage 2**. Reuses Stage 1's synthesis verdict.
264
+
265
+ **How it works**:
266
+ 1. **Auto-stage worktree** with `git add -A` (opt out via `CCG_NO_AUTO_ADD=1`)
267
+ 2. Read state file from `<repo>/.git/ccg/last-review.json` (written by Stage 1)
268
+ 3. Verify the staged diff hash matches the reviewed hash
269
+ 4. Apply the recorded verdict (`merge` / `fix-required` / `discuss`)
270
+ 5. `git commit -m "msg"`
271
+ 6. Delete the state file (one-shot — next commit needs a fresh review)
272
+
273
+ **State file contents**:
274
+ ```json
275
+ {
276
+ "ts": "2026-05-29T11:30:00Z",
277
+ "diff_hash": "acb9adaab6516b3e7fc66fed10dd8a8d",
278
+ "diff_source": "worktree",
279
+ "verdict": "merge",
280
+ "classification": "AGREEMENT",
281
+ "mode": "balanced"
102
282
  }
103
283
  ```
104
284
 
105
- You open Claude Code and type:
285
+ **Verdicts**:
286
+ | Verdict | Action |
287
+ |---|---|
288
+ | `merge` | ✅ Commit allowed |
289
+ | `discuss` | ⚠️ Allowed by default (set `CCG_GATE_DISCUSS=block` to enforce) |
290
+ | `fix-required` | ❌ Commit blocked |
291
+
292
+ **Failure modes**:
293
+ | Scenario | Result |
294
+ |---|---|
295
+ | No prior review | ❌ Error: "Run 'ccg review' first" (or set `CCG_REVIEW=off` to skip) |
296
+ | Diff changed since review | ❌ Hash mismatch — re-run review |
297
+ | Bypass diff check | `CCG_COMMIT_FORCE=1 ccg commit ...` |
298
+ | Auto-stage disabled | `CCG_NO_AUTO_ADD=1 ccg commit ...` — caller must `git add` first |
299
+ | Review disabled | `CCG_REVIEW=off ccg commit ...` — skips state check entirely |
300
+
301
+ **Why no LLM in Stage 2?**
302
+
303
+ The original design ran 2 parallel models here for adversarial robustness — but `ccg review` already does that (2 models + Claude synthesis). Repeating it on commit doubles cost and latency without adding signal. Reusing Stage 1's verdict is faster, cheaper, and equally safe.
106
304
 
305
+ ---
306
+
307
+ ### Stage 3 — AI Merge (`ccg merge <target>`) ⭐ **Core Competitive Advantage**
308
+
309
+ **Purpose**: Resolve merge conflicts professionally and reliably.
310
+
311
+ **Model strategy** (3-tier fallback):
312
+ 1. **Bailian** (primary) — Aliyun-hosted models (most reliable for code)
313
+ 2. **Claude** (secondary) — direct Anthropic API
314
+ 3. **Codex + Gemini** (tertiary) — parallel race
315
+ 4. `NEEDS_HUMAN_DECISION` if all fail
316
+
317
+ **Conflict classification** (only `content` goes to AI):
318
+ | Kind | Handling |
319
+ |---|---|
320
+ | `content` | AI resolution |
321
+ | `binary` | NEEDS HUMAN |
322
+ | `submodule` | NEEDS HUMAN |
323
+ | `symlink` | NEEDS HUMAN |
324
+ | `delete_modify` | NEEDS HUMAN |
325
+ | `both_deleted` | NEEDS HUMAN |
326
+ | `added_one_side` | NEEDS HUMAN |
327
+ | `both_added` | NEEDS HUMAN |
328
+
329
+ **Pipeline**:
107
330
  ```
108
- /ccg
331
+ checkout target → backup branch → git merge --no-commit
332
+ ↓ (for each conflict file)
333
+ classify → parse <<<<<<< blocks
334
+ → Bailian resolution
335
+ ↓ (if failed)
336
+ Codex + Gemini parallel
337
+ ↓ (if both failed)
338
+ NEEDS_HUMAN_DECISION
339
+ → validate (no markdown fences, no conflict markers, non-empty)
340
+ → atomic file rewrite (mktemp + mv, preserve permissions)
341
+ → git add (if resolved)
342
+
343
+ commit (if all clean) | leave uncommitted (if any needs-human)
109
344
  ```
110
345
 
111
- After ~30 seconds you see something like this — **real output**, not a placeholder:
346
+ **Safety guarantees**:
347
+ - Backup branch created BEFORE merge (`ccg-backup/<target>-<timestamp>-<pid>-<rand>`)
348
+ - Aborts if working tree is dirty, detached HEAD, or mid-operation
349
+ - Rejects diverged remote
350
+ - Per-conflict nonce prevents OURS/THEIRS injection
351
+ - Validates resolved content (no markdown fences, no conflict markers, non-empty)
352
+ - Atomic file replacement (`mktemp` + `mv`)
353
+ - Preserves file permissions and refuses to write through symlinks
354
+ - **Never silently drops code** — fails to NEEDS_HUMAN
355
+ - Real-time progress: `[3/12] src/auth.js ... ✅ resolved`
356
+ - Limits max conflicts (default 50, override via `CCG_MERGE_MAX_CONFLICTS`)
112
357
 
358
+ ---
359
+
360
+ ### Stage 4 — Pre-Push Analysis (`ccg push <remote> <branch>`)
361
+
362
+ **Purpose**: Show a comprehensive, graphical report before pushing — let user decide informed.
363
+
364
+ **Model strategy**: Bailian LLM for risk scoring (falls back to deterministic rules).
365
+
366
+ **Report sections**:
113
367
  ```
114
- 📍 Scope: worktree · 1 file · +4 -1 lines
115
- 🎯 Mode: quality (risk=65 · auth+35 size>0+5 crypto-mention+25)
116
- 🩺 Both reviewers OK: Codex ✓ · Gemini ✓
117
- 💰 Cost: $0.041
368
+ ╔══════════════════════════════════════════════════════════╗
369
+ ║ 🚀 CCG Pre-Push Analysis Report 🚀 ║
370
+ ╚══════════════════════════════════════════════════════════╝
118
371
 
119
- ═══ AGREEMENT (2) both flagged, low signal ═══
120
- • auth/login.go:3 — sha256 wasn't a password hash; bcrypt is correct
121
- • auth/login.go:5 — handle the bcrypt error explicitly (you do)
372
+ 📍 Branch / Remote / HEAD / Author / Time
122
373
 
123
- ═══ DIVERGENCE (1) — the models disagreed ★ you decide ═══
374
+ ┌─ Commit Summary ─────────────────────────────────────┐
375
+ │ Ahead: N commit(s) / Behind: M commit(s)
376
+ └──────────────────────────────────────────────────────┘
124
377
 
125
- auth/login.go:6 how to compare bcrypt hashes
126
- 🔵 Codex: "Wrap with subtle.ConstantTimeCompare to prevent timing attacks
127
- even with bcrypt."
128
- 🟢 Gemini: "bcrypt.CompareHashAndPassword is already constant-time. Wrapping
129
- it is cargo-cult and can mask bugs (length mismatch panics)."
130
- ⚖️ Claude: Gemini is correct. bcrypt.CompareHashAndPassword is the canonical
131
- comparison; ConstantTimeCompare on its raw output is a category
132
- error — you'd be comparing the freshly-hashed `pw` against the
133
- stored hash, but bcrypt salts each hash uniquely so direct
134
- comparison ALWAYS returns false.
135
- ➡️ Action: Replace the ConstantTimeCompare line with:
136
- `err := bcrypt.CompareHashAndPassword(u.Hash, []byte(pw))`
137
- `return err == nil`
378
+ 📝 Commits with quality markers (✓ conventional / ⚠ WIP)
138
379
 
139
- ═══ BLINDSPOT (1) — neither saw, Claude suspects ═══
140
- Error path: returning `false` on bcrypt error is correct for the caller but
141
- silently swallows infrastructure errors (e.g. bcrypt OOM). Log the error.
380
+ ┌─ Code Changes ───────────────────────────────────────┐
381
+ │ Files / Lines added / Lines removed + visual bar
382
+ └──────────────────────────────────────────────────────┘
142
383
 
143
- ═══ VERDICT: fix-required ═══
144
- The comparison logic as written will always reject valid passwords. Apply
145
- the DIVERGENCE action, add error logging, and you're good to merge.
146
- ```
384
+ 📂 File Categories: 💻 Code / 🧪 Tests / 📖 Docs / ⚙️ Config
147
385
 
148
- ### How to read this output
386
+ 🚨 SENSITIVE FILES DETECTED (.env, *.pem, credentials, ...)
149
387
 
150
- | Section | What it means | What to do |
151
- |---|---|---|
152
- | **AGREEMENT** | Both Codex and Gemini flagged the same thing. Your single-source Claude likely catches these too — **low new information**. | Skim, fix if not already done. |
153
- | **DIVERGENCE** ★ | The two models disagreed. **This is the whole reason ccg exists.** Claude's "Action" line gives you a recommendation, but you're the final decider. | Read carefully. Apply Claude's call or override it. |
154
- | **BLINDSPOT** | Neither model raised it, but Claude noticed something while synthesizing. **Use sparingly** — limit 2 per run. | Treat as a hint, not gospel. |
155
- | **VERDICT** | `merge` / `fix-required` / `discuss`. One-line summary. | Use as merge gate. |
388
+ ┌─ Risk Assessment ────────────────────────────────────┐
389
+ │ Score: 🔴 CRITICAL (85) — auth + payment
390
+ │ [████████████████████████████████████████████]
391
+ └──────────────────────────────────────────────────────┘
156
392
 
157
- After the review, `ccg_ledger_record` writes one JSONL line to your ledger. Two weeks from now you can:
393
+ 📊 Push Quality Scorecard:
394
+ ✅ Conventional commit messages
395
+ ✅ Code changes accompanied by tests
396
+ ❌ Sensitive files in changeset
397
+ ✅ Up to date with remote
398
+ ⚠️ High risk score — review carefully
158
399
 
159
- ```bash
160
- source ~/.claude/commands/ccg.sh
161
- ccg_ledger_query "auth/login.go"
162
- # → "auth/login.go: 3 reviews · last 2026-05-23 (fix-required) · 2026-05-09 (merge) · 2026-04-28 (discuss)"
400
+ ┌─ Recommendation ─────────────────────────────────────┐
401
+ │ 🔴 NOT RECOMMENDED (3/5 checks passed)
402
+ └──────────────────────────────────────────────────────┘
403
+
404
+ ┌─ Decision ───────────────────────────────────────────┐
405
+ │ y — push | n — cancel | d — view diff | l — view log
406
+ └──────────────────────────────────────────────────────┘
163
407
  ```
164
408
 
165
- ## Configure (defaults are usually fine)
409
+ **Quality checks**:
410
+ 1. Conventional commit messages (`feat|fix|chore|...:`)
411
+ 2. Test files updated alongside code
412
+ 3. No sensitive files (`.env`, `*.pem`, `credentials`, etc.)
413
+ 4. Up to date with remote (not behind)
414
+ 5. Risk level acceptable (<80)
415
+
416
+ ---
417
+
418
+ ### One-Click Ship (`ccg ship [target] [msg]`)
419
+
420
+ **Purpose**: Combine review → commit → merge in a single command.
166
421
 
167
- Mode and model picks are automatic. Override only when needed:
422
+ **Pipeline**:
423
+ 1. `ccg review` — run full Stage 1 review
424
+ 2. `ccg commit` — commit with review gate (only if verdict is `merge`)
425
+ 3. `ccg merge <target>` — merge into target branch
168
426
 
427
+ **Usage**:
169
428
  ```bash
170
- CCG_MODE=quality /ccg # force quality models on any diff
171
- CCG_CODEX_MODEL=o3 /ccg # override one model
172
- CCG_NO_CACHE=1 /ccg # skip 24h cache for this call
429
+ # Ship to main with auto-detected target
430
+ ccg ship
431
+
432
+ # Ship to specific branch
433
+ ccg ship main
434
+
435
+ # Ship with custom commit message
436
+ ccg ship main "feat: add user auth"
173
437
  ```
174
438
 
175
- Common knobs (full list in [Architecture → §5](docs/ARCHITECTURE.md#5-extension-points)):
439
+ **When to use**: For rapid iteration when you want the full review-commit-merge pipeline in one command.
176
440
 
177
- | Variable | Default | Purpose |
178
- |---|---|---|
179
- | `CCG_MODE` | `auto` | `auto` / `cost` / `balanced` / `quality` |
180
- | `CCG_CACHE_TTL_HOURS` | `24` | Cache TTL |
181
- | `CCG_MAX_PROMPT_KB` | `100` | Per-call prompt size cap |
441
+ ---
442
+
443
+ ## Model Strategy
182
444
 
183
- Cost reference (USD per call, after cache):
445
+ ### Four Independent Providers
184
446
 
185
- | Mode | Codex | Gemini | Typical cost |
447
+ | Provider | API Path | Required Env | Custom Endpoint |
186
448
  |---|---|---|---|
187
- | `cost` | gpt-5-nano | gemini-2.5-flash-lite | ~$0.0007 |
188
- | `balanced` | gpt-5-mini | gemini-2.5-flash | ~$0.0046 |
189
- | `quality` | gpt-5 | gemini-2.5-pro | ~$0.0440 |
449
+ | `codex` | Codex CLI (calls OpenAI) | `codex` binary | `CCG_CODEX_BASE_URL` / `OPENAI_BASE_URL` |
450
+ | `claude` | Direct Anthropic API | `ANTHROPIC_API_KEY` or `CLAUDE_API_KEY` | `CCG_CLAUDE_BASE_URL` / `ANTHROPIC_BASE_URL` |
451
+ | `gemini` | Gemini CLI (calls Google) | `gemini` binary + `GEMINI_API_KEY` | `CCG_GEMINI_BASE_URL` / `GEMINI_BASE_URL` |
452
+ | `bailian` | Direct Aliyun Bailian API | `BAILIAN_API_KEY` | `CCG_BAILIAN_BASE_URL` |
190
453
 
191
- See accumulated spend any time:
454
+ ### Three Modes
192
455
 
193
- ```bash
194
- source ~/.claude/commands/ccg.sh
195
- ccg_usage --this-month
196
- ```
456
+ CCG auto-selects mode based on risk score, or you can force it via `CCG_MODE`.
457
+
458
+ | Risk Score | Auto Mode | Strategy |
459
+ |---|---|---|
460
+ | `< 30` | `cost` | Use cheap Bailian models everywhere |
461
+ | `30 – 70` | `balanced` | Mix of mid-tier models per provider |
462
+ | `> 70` | `quality` | Top-tier models per provider |
463
+
464
+ ### Model Per Mode
465
+
466
+ | Mode | codex | claude | gemini | bailian |
467
+ |---|---|---|---|---|
468
+ | **`cost`** | `gpt-5-mini` | `claude-haiku-4-5` | `gemini-2.5-flash-lite` | `qwen-3.5-haiku` |
469
+ | **`balanced`** | `gpt-5.4` | `claude-sonnet-4-6` | `gemini-2.5-flash` | `qwen-3.6` |
470
+ | **`quality`** | `gpt-5.5` | `claude-opus-4-7` | `gemini-3.5-flash` | `qwen-3.7` |
471
+
472
+ ### Per-Stage Model Usage
197
473
 
198
- ## Not for
474
+ | Stage | Uses Models? | Which Models |
475
+ |---|---|---|
476
+ | **Diff Capture** | ❌ | Pure git ops |
477
+ | **Risk Score** | ✅ Bailian LLM | Falls back to rule engine |
478
+ | **Stage 1: Review** | ✅ **any 2 slots in parallel** | Default: codex + gemini. Same provider can run twice with different models (e.g., `bailian:qwen-3.7 bailian:deepseek-v4`) |
479
+ | **Synthesize** | ✅ 1 model | **Claude preferred** (reserved meta-reviewer) → fallback: codex → bailian → gemini |
480
+ | **Stage 2: Commit Gate** | ❌ **NO LLM** | Reuses Stage 1 synthesis verdict (zero extra cost) |
481
+ | **Stage 3: Merge Conflicts** | ✅ **3-tier fallback** | Bailian → Claude → Codex+Gemini |
482
+ | **Stage 4: Push Check** | ✅ Bailian LLM | Risk scoring only |
483
+
484
+ ### Available Bailian Models
485
+
486
+ | Model | Tier | Input ¥/1M | Output ¥/1M | Notes |
487
+ |---|---|---|---|---|
488
+ | `qwen-3.7` | quality | 0.30 | 0.90 | Latest Qwen |
489
+ | `deepseek-v4` | quality | 0.35 | 1.05 | Top reasoning |
490
+ | `kimi-k2.6` | quality | 0.32 | 0.96 | Long context |
491
+ | `glm-5.1` | quality | 0.28 | 0.84 | Multimodal |
492
+ | `qwen-3.6` | balanced | 0.25 | 0.75 | |
493
+ | `mimo-v2.5-pro` | balanced | 0.22 | 0.66 | |
494
+ | `qwen-3.6-plus` | balanced | 0.20 | 0.60 | |
495
+ | `qwen-3.5-sonnet` | balanced | 0.15 | 0.45 | |
496
+ | `deepseek-v4-lite` | balanced | 0.18 | 0.54 | |
497
+ | `kimi-k2.6-lite` | balanced | 0.16 | 0.48 | |
498
+ | `glm-5.1-lite` | balanced | 0.14 | 0.42 | |
499
+ | `mimo-v2.5` | cost | 0.11 | 0.33 | |
500
+ | `qwen-3.5-haiku` | cost | 0.05 | 0.15 | Cheapest |
199
501
 
200
- - IDEs other than Claude Code (try [zen-mcp-server](https://github.com/BeehiveInnovations/zen-mcp-server))
201
- - Replacing static analysis (pair with Semgrep / CodeQL)
202
- - Auto-running on every PR (ccg is a triage tool, not a bot)
203
- - Streaming or multi-turn conversation
502
+ ---
204
503
 
205
- ## Architecture & contributing
504
+ ## Configuration
206
505
 
207
- ccg is **7 layers**, only the top one is "divergence detection". The other six (cache, ledger, usage, risk routing, smart diff, safe CLI scheduling) each independently solve a real problem. Read [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) before changing anything in `ccg.sh`.
506
+ ### Environment Variables
208
507
 
209
- Tests:
508
+ | Variable | Default | Description |
509
+ |---|---|---|
510
+ | **Switches / Mode** | | |
511
+ | `CCG_MODE` | auto | `cost` / `balanced` / `quality` |
512
+ | `CCG_REVIEW` | `on` | Master switch: `on` / `off` (when off, `ccg review` is a no-op and `ccg commit` skips state check) |
513
+ | `CCG_PROVIDERS` | auto (depends on mode) | Providers for Stage 1 (max 2 parallel). quality: codex+gemini, cost/balanced: bailian pair. Claude is reserved for Synthesis by default. |
514
+ | **Provider models** | | |
515
+ | `CCG_CODEX_MODEL` | by mode | Override Codex model |
516
+ | `CCG_CLAUDE_MODEL` | by mode | Override Claude model |
517
+ | `CCG_GEMINI_MODEL` | by mode | Override Gemini model |
518
+ | `CCG_BAILIAN_MODEL` | by mode | Override Bailian model |
519
+ | **API keys** | | |
520
+ | `BAILIAN_API_KEY` | — | Bailian (Aliyun) API key |
521
+ | `ANTHROPIC_API_KEY` / `CLAUDE_API_KEY` | — | Anthropic API key |
522
+ | `GEMINI_API_KEY` | — | Google Gemini API key |
523
+ | **Custom endpoints (proxies)** | | |
524
+ | `CCG_CODEX_BASE_URL` / `OPENAI_BASE_URL` | OpenAI | Codex / OpenAI proxy URL |
525
+ | `CCG_CLAUDE_BASE_URL` / `ANTHROPIC_BASE_URL` | api.anthropic.com | Claude proxy URL |
526
+ | `CCG_GEMINI_BASE_URL` / `GEMINI_BASE_URL` | Google | Gemini proxy URL |
527
+ | `CCG_BAILIAN_BASE_URL` | dashscope.aliyuncs.com | Bailian proxy URL |
528
+ | **Timeouts / Parameters** | | |
529
+ | `CCG_CODEX_TIMEOUT` | 240 | Codex timeout (seconds) |
530
+ | `CCG_GEMINI_TIMEOUT` | 120 | Gemini timeout (seconds) |
531
+ | `CCG_BAILIAN_TIMEOUT` | 120 | Bailian timeout (seconds) |
532
+ | `CCG_CLAUDE_TIMEOUT` | 120 | Claude timeout (seconds) |
533
+ | `CCG_BAILIAN_TEMP` | 0.7 | Bailian temperature |
534
+ | `CCG_BAILIAN_MAX_TOKENS` | 4096 | Bailian max tokens |
535
+ | `CCG_BAILIAN_RETRIES` | 3 | Bailian retry count |
536
+ | `CCG_CLAUDE_RETRIES` | 3 | Claude retry count |
537
+ | **Gate / Commit** | | |
538
+ | `CCG_GATE_OFFLINE` | 0 | Set to 1 to skip Stage 2 review (legacy gate) |
539
+ | `CCG_GATE_DISCUSS` | allow | Set to `block` to block discuss verdict |
540
+ | `CCG_NO_AUTO_ADD` | 0 | Stage 2: skip auto `git add -A`, use only what's already staged |
541
+ | `CCG_COMMIT_FORCE` | 0 | Stage 2: bypass diff-hash check (force commit even if diff changed) |
542
+ | `CCG_AUTOCOMMIT_ALL` | 0 | Auto-commit all changes (including untracked) |
543
+ | `CCG_AUTOCOMMIT_DRY_RUN` | 0 | Dry run mode for autocommit |
544
+ | `CCG_DIFF_CACHED_ONLY` | 0 | Only use cached diff |
545
+ | **Merge** | | |
546
+ | `CCG_MERGE_DRY_RUN` | 0 | Stage 3: resolve but don't commit |
547
+ | `CCG_MERGE_NO_AI` | 0 | Stage 3: skip AI resolution |
548
+ | `CCG_MERGE_NO_FETCH` | 0 | Stage 3: skip remote fetch |
549
+ | `CCG_MERGE_MAX_CONFLICTS` | 50 | Stage 3: max conflict files |
550
+ | `CCG_MERGE_KEEP_BACKUP` | 0 | Stage 3: keep backup branch after success |
551
+ | **Cache / Ledger / Reports** | | |
552
+ | `CCG_NO_CACHE` | 0 | Disable prompt cache |
553
+ | `CCG_CACHE_TTL_HOURS` | 24 | Prompt cache TTL |
554
+ | `CCG_CACHE_DIR` | XDG default | Custom cache directory |
555
+ | `CCG_MAX_PROMPT_KB` | 100 | Max prompt size in KB |
556
+ | `CCG_USAGE_LOG` | XDG default | Custom usage log path |
557
+ | `CCG_LEDGER_LOG` | XDG default | Custom ledger log path |
558
+ | `CCG_LEDGER_MAX_LINES` | 10000 | Max ledger lines before rotation |
559
+ | `CCG_NO_HISTORY` | 0 | Disable review history injection |
560
+ | `CCG_HISTORY_MAX` | 3 | Max historical reviews to inject |
561
+ | `CCG_NO_REPORT` | 0 | Disable report persistence |
562
+ | `CCG_REPORT_DIR` | .ccg/reports | Custom report directory |
563
+ | `CCG_KEEP_ARTIFACTS` | 0 | Keep workdir for debugging |
564
+ | **Other** | | |
565
+ | `CCG_ALLOW_SAME_VENDOR` | 0 | Allow same vendor in Stage 1 slots |
566
+ | `CCG_SYNTH_PROVIDER` | auto | Override synthesizer provider |
567
+ | `CCG_RISK_LLM` | 0 | Enable LLM-based risk scoring |
568
+
569
+ ### Usage Examples
210
570
 
211
571
  ```bash
212
- bash tests/test_ccg.sh # 99 regression tests, ~31s
213
- REAL_CLI=1 bash tests/test_ccg.sh # +2 live API tests (incurs cost)
572
+ # Force quality mode for a critical review
573
+ CCG_MODE=quality ccg review
574
+
575
+ # Use only Bailian (offline-friendly for China)
576
+ CCG_PROVIDERS="bailian" ccg review
577
+
578
+ # Mix providers — codex + claude (requires quality mode)
579
+ CCG_MODE=quality CCG_PROVIDERS="codex claude" ccg review
580
+
581
+ # Specific Bailian model
582
+ CCG_BAILIAN_MODEL=deepseek-v4 ccg review
583
+
584
+ # Use OpenAI through proxy (e.g., for China)
585
+ CCG_CODEX_BASE_URL="https://your-proxy.com/v1" ccg review
586
+
587
+ # Use Claude through proxy (e.g., third-party gateway)
588
+ CCG_CLAUDE_BASE_URL="https://tokensolo.com" ccg review
589
+
590
+ # Dry-run merge (resolve but don't commit)
591
+ CCG_MERGE_DRY_RUN=1 ccg merge main
592
+
593
+ # Skip AI merge resolution (just detect conflicts)
594
+ CCG_MERGE_NO_AI=1 ccg merge main
214
595
  ```
215
596
 
216
- ## License & credits
597
+ ---
598
+
599
+ ## Architecture
600
+
601
+ ```
602
+ ccg/
603
+ ├── ccg # Entry point (4-line delegator)
604
+ ├── ccg.sh # Core engine (~3000 lines)
605
+ │ ├── _ccg_xdg_* / _ccg_vcs_* # XDG paths + git abstraction
606
+ │ ├── ccg_init / ccg_preflight # Workdir setup
607
+ │ ├── ccg_diff_capture # 4-level diff fallback
608
+ │ ├── ccg_risk_score # Bailian LLM + rule engine
609
+ │ ├── ccg_codex / ccg_gemini # Provider runners (with custom endpoint support)
610
+ │ ├── ccg_claude / _ccg_claude_retry # Direct Anthropic API (with custom endpoint)
611
+ │ ├── _ccg_bailian_retry # Bailian with retry/backoff
612
+ │ ├── ccg_synthesize # AGREEMENT/DIVERGENCE/BLINDSPOT
613
+ │ ├── ccg_precommit_gate # Stage 2 commit gate
614
+ │ └── ccg_merge # Stage 3 AI merge (Bailian → Claude → Codex+Gemini)
615
+ │ ├── _ccg_classify_conflict # content/binary/submodule/...
616
+ │ ├── _ccg_parse_conflicts # extract <<<<<<<>>>>>>> blocks
617
+ │ ├── _ccg_resolve_one_conflict # 3-tier AI resolution
618
+ │ └── _ccg_apply_resolutions # atomic file rewrite
619
+ ├── ccg-bailian-models.sh # 15-model Bailian registry
620
+ ├── ccg-bailian-integration.sh # Bailian API call helpers
621
+ ├── ccg-multi-provider.sh # 4-provider orchestration
622
+ ├── ccg-workflow.sh # 4-stage workflow entry points
623
+ └── ccg.md # Claude Code slash command spec
624
+
625
+ docs/
626
+ ├── README.zh-CN.md / .ja.md / .ko.md # Translations
627
+ ├── ARCHITECTURE.md (+ 3 translations) # Deep architecture
628
+ └── CHANGELOG.md # Version history
629
+ ```
630
+
631
+ ### Storage (XDG-compliant)
632
+
633
+ | Path | Content |
634
+ |---|---|
635
+ | `$XDG_DATA_HOME/ccg/usage.log` | Token usage + cost log |
636
+ | `$XDG_DATA_HOME/ccg/ledger.jsonl` | Per-review JSONL ledger |
637
+ | `$XDG_CACHE_HOME/ccg/cache/` | Prompt hash → result cache (24h TTL) |
638
+ | `$XDG_CONFIG_HOME/ccg/` | User config |
639
+
640
+ Legacy `~/.ccg/*` auto-migrated on first run.
641
+
642
+ ---
643
+
644
+ ## Documentation
645
+
646
+ - [Architecture deep-dive](docs/ARCHITECTURE.md) ([中文](docs/ARCHITECTURE.zh-CN.md) · [日本語](docs/ARCHITECTURE.ja.md) · [한국어](docs/ARCHITECTURE.ko.md))
647
+ - [Capabilities reference](docs/CAPABILITIES.md) — full feature inventory grounded in the source (中文)
648
+ - [Changelog](docs/CHANGELOG.md)
649
+ - [Slash command spec](ccg.md) — Claude Code `/ccg` command
650
+
651
+ ---
217
652
 
218
- MIT — see [LICENSE](LICENSE).
653
+ ## License
219
654
 
220
- Built on [oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode)'s original `/ccg` concept · Claude Code · OpenAI Codex CLI · Google Gemini CLI.
655
+ MIT