commitgate 0.9.1 β†’ 0.9.3

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.en.md CHANGED
@@ -1,608 +1,98 @@
1
- # CommitGate
2
-
3
- 🌐 [ν•œκ΅­μ–΄](./README.md) Β· **English**
4
-
5
- **A commit gate that blocks AI-generated code from being committed until Codex has reviewed and approved it.**
6
-
7
- AI coding agents can move quickly, but unreviewed changes should not go straight into your history. CommitGate wraps each change in a REQ ticket and only allows the staged tree approved by Codex to be committed. If the code changes after approval, or if evidence is missing, it fails closed.
8
-
9
- > **⚠️ Two things to know before you start.**
10
- >
11
- > 1. **Review sends your staged diff off-machine.** `req:review-codex` passes the **entire** `git diff --cached` to Codex (OpenAI). Codex reads your repository root under `--sandbox read-only`, so files outside the diff can be read too. There is **no** masking, filtering, or size cap. Check the staged content for credentials, tokens, and personal data before running a review.
12
- > 2. **No git hook is installed.** Running `git commit` directly instead of `req:commit` bypasses the gate, the approval binding, and the evidence trail. CommitGate's enforcement keeps a **cooperating agent on the contract's rails** β€” it is not a barrier against a human going around it.
13
-
14
- [![CI](https://github.com/sol5288/commitgate/actions/workflows/ci.yml/badge.svg)](https://github.com/sol5288/commitgate/actions/workflows/ci.yml)
15
- [![npm version](https://img.shields.io/npm/v/commitgate.svg)](https://www.npmjs.com/package/commitgate)
16
- [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
17
-
18
- ---
19
-
20
- ## Quick Start
21
-
22
- Run this from your project root. The project must be a **git repository with a `package.json`**.
23
-
24
- ```sh
25
- # If this is a fresh folder that is not yet a git repo or has no package.json, first:
26
- git init
27
- npm init -y
28
-
29
- # 1) Install CommitGate as a devDependency β€” this is where the runtime lives:
30
- npm install -D commitgate
31
-
32
- # 2) Add config, contract, schemas, and the req:* scripts to your project:
33
- npx commitgate init
34
-
35
- codex --version
36
- codex login status
37
- ```
38
-
39
- > **Why two steps?** CommitGate does **not** copy its runtime code into your project. Step 1 puts the runtime in `node_modules/commitgate`; step 2 adds only **governance assets** (config, contract, schemas, persona) plus `req:* = commitgate <verb>` scripts.
40
- > Removing the runtime is a single `npm uninstall -D commitgate`. **For updates, follow the [Upgrading (0.x)](#upgrading-0x) section below** β€” the runtime (`node_modules`) is bumped with `npm`, but the vendored assets (schemas, persona) in your project must be re-synced separately with `commitgate sync`, and a 0.x caret range (`^0.y`) does not cross a minor automatically.
41
- > `init` **stops** if `devDependencies.commitgate` is not declared β€” there would be no runtime for `req:*` to point at.
42
-
43
- Installation writes files but never commits them. `req:new` **requires a clean working tree**, so commit the scaffold first. The installer's `λ‹€μŒ:` (next steps) output prints the exact paths to stage.
44
-
45
- ```sh
46
- git add -- <the paths the installer printed>
47
- git status # confirm only what you intended is staged
48
- git commit -m "chore: install commitgate"
49
- ```
50
-
51
- > **Do not stage everything (`-A` / `.`).** Unrelated changes and untracked files such as `.env` would be swept into the commit, and the next `req:review-codex` transmits that staged diff in full to an external service.
52
- > Park any changes that predate the install **by pathspec** after the install commit: `git stash push -u -- <paths>`.
53
- > Without `-u`, untracked files remain and `req:new` stays blocked; without the pathspec, a bare `git stash -u` also sweeps up directories that are not ignored, such as `node_modules/`. The installer prints that path list too.
54
-
55
- **You do not paste a long prompt.** Installation lays down agent entrypoints for you.
56
-
57
- | File | Read by |
58
- |---|---|
59
- | `AGENTS.md` | Codex CLI, Cursor β€” **the contract** |
60
- | `.claude/skills/commitgate/SKILL.md` | Claude Code (auto-discovered β€” the model decides whether to use it) |
61
- | `.claude/commands/req.md` | Claude Code (`/req` explicit call) |
62
- | `.cursor/rules/commitgate.mdc` | Cursor (`alwaysApply`) |
63
- | `CLAUDE.md` | Claude Code (always loaded) β€” created only if absent |
64
-
65
- > **On a fresh install, `CLAUDE.md` and `AGENTS.md` open with a self-sufficient Quick Start** (clarify the four-box requirement β†’ `req:new` β†’ the `req:next` loop). Because these are always-loaded channels, the agent picks the correct first action on the first request without reading the full contract. An existing `CLAUDE.md`/`AGENTS.md` is preserved β€” the Quick Start is not injected in that case.
66
-
67
- Just give the agent a requirement.
68
-
69
- ```text
70
- /req Add a profile edit API
71
-
72
- - What: PATCH /profile to change nickname and bio
73
- - Why: users cannot change their profile after signup
74
- - Constraints: reuse the existing auth middleware, no schema change
75
- - Done when: unit tests pass, unauthorized users get 403
76
- ```
77
-
78
- Outside Claude Code you can skip the slash command and state the requirement directly β€” `.cursor/rules` and `AGENTS.md` load the rules. If the four fields are missing, the agent asks first.
79
-
80
- The agent's first reply should look roughly like this.
81
-
82
- ```text
83
- REQ-2026-002 created
84
- Branch: feat/req-2026-002-profile-edit-api
85
- Phases:
86
- - phase-1: implement PATCH /profile
87
- - phase-2: tests and regression checks
88
- Control points: before req:commit --run / [B1] before a direct push to main (or [I1] open PR β†’ [I2] merge)
89
- ```
90
-
91
- ### The agent follows whatever `req:next` says
92
-
93
- The agent never guesses the next action. The tool computes it from `state.json` and git state.
94
-
95
- ```sh
96
- npm run req:next -- 2026-002
97
- ```
98
-
99
- ```text
100
- [req:next] RUN REQ-2026-002
101
- phase `phase-1`의 staged 변경을 λ¦¬λ·°λ°›λŠ”λ‹€.
102
-
103
- $ npm run req:review-codex -- 2026-002 --kind phase --phase phase-1 --run
104
- ```
105
-
106
- | kind | Meaning | exit |
107
- |---|---|---|
108
- | `RUN` | Run the printed command verbatim, then `req:next` again | 0 |
109
- | `AGENT` | Work the tool cannot do (implement, write docs, `git add`) | 0 |
110
- | `AWAIT_HUMAN` | **Control point** β€” do not proceed without the exact approval sentence | 10 |
111
- | `DONE` | Nothing left for the tool. Integration is a separate control point | 11 |
112
- | `BLOCKED` | Escalate to a human. Do not retry the same review | 2 |
113
-
114
- Use `--json` for machine-readable output. It is **read-only** and changes no state.
115
-
116
- Repeat this loop without stopping and it drives design β†’ Codex review β†’ implementation β†’ re-review β†’ commit. You only confirm at `AWAIT_HUMAN`.
117
-
118
- > **Per-phase auto-commit (opt-in).** By default the loop stops at `AWAIT_HUMAN` before every phase commit. Set
119
- > `"phaseCommit": { "autoApprove": "low-only" }` in `req.config.json` and Codex-approved phases of **LOW-risk**
120
- > tickets commit without a human stop (`req:next` issues `req:commit --run` as a RUN), moving the single human
121
- > confirmation to just **before the feature→main merge** (the terminal becomes `AWAIT_HUMAN` (integration) instead
122
- > of `DONE`). **HIGH-risk tickets still stop at every phase** regardless of the policy. The Codex review gate is
123
- > unchanged either way β€” only the *human stop* on LOW phases is removed.
124
-
125
- ### The reviewer persona is injected by the tool
126
-
127
- `req:review-codex` puts `workflow/review-persona.md` in as the **first block** of the prompt. It is identical whether a human, Cursor, or Claude runs the command β€” it does not live where an agent can forget it. If the file is missing or empty, the review stops fail-closed.
128
-
129
- Edit it for your project, or point `reviewPersonaPath` in `req.config.json` at a different file. Set it to `null` to disable β€” but **delta design reviews still inject the built-in delta contract** (the contract that tells the reviewer to re-check only what changed since the approved baseline, so it is attached regardless of the configured persona).
130
-
131
- ### Design re-reviews narrow to a delta
132
-
133
- Once a design is approved, CommitGate remembers that snapshot of the design docs (default `00/01/02`, configurable via `designDocs`) as a baseline. When you then edit the design and re-review, the prompt is built so the reviewer assesses **only the changed documents and their direct impact**. Changed docs are tagged `[변경됨 β€” 심사 λŒ€μƒ]` (changed β€” under review), unchanged docs `[승인 baseline β€” λ³€κ²½ μ—†μŒ, μ°Έμ‘°]` (approved baseline β€” unchanged, for reference), with a contract not to re-litigate the approved areas. Unchanged docs carry only an omission marker instead of their body, to save tokens. This reduces the failure mode where a small post-approval edit triggered a full re-review and the approval got reverted.
134
-
135
- If a change is too fundamental to judge as a delta, the reviewer requests a full re-review with `full_review_requested: "yes"` (which must come with `commit_approved: "no"`). The baseline is then cleared so the next design review returns to full mode; once that design is approved again, a new baseline is captured and delta review resumes.
136
-
137
- Both integration paths are valid: **through a PR (optional)** and **direct push**. A PR is not mandatory. But a direct push to a protected branch **bypasses the required status checks**, so it needs a separate "branch protection bypassλ₯Ό μ‚¬μš©ν•œ direct push 승인" β€” holding bypass permission is not approval. In that case CI runs **after** the push, so its green is post-hoc verification, and the agent must not omit that from its report. tag, npm publish, and GitHub release are control points of their own, requested after CI is green and never bundled with the integration approval. See [AGENTS.template.md](AGENTS.template.md) and [docs/RELEASING.md](docs/RELEASING.md) for the full contract.
138
-
139
- ---
140
-
141
- ## What Does It Enforce?
142
-
143
- CommitGate is designed to block **unreviewed changes from being committed**, not just to wrap commands.
144
-
145
- - No Codex approval means no commit.
146
- - If the approved staged tree differs from the current staged tree, the commit is blocked.
147
- - Workflow files such as `state.json` and `responses/` cannot be mixed into the source commit.
148
- - If Codex CLI is missing or fails, the workflow fails instead of silently passing.
149
- - Review exit codes are outcome-based: `0` approved, `1` invalid/fail-closed, `2` blocked/no actionable findings, `3` needs fix.
150
- - A no-findings/no-approval response is BLOCKED, not NEEDS_FIX, so agents must not loop on it.
151
- - Re-review attempts are counted per open `(review_kind, phase_id)` review series. With `{ autoBudget: 5, hardCap: 8 }`, rounds 1–5 run automatically, rounds 6–8 each require a human exception record, and once `hardCap` is spent the next attempt (round 9 onward) is blocked even with an exception β€” this prevents infinite re-review loops. An approval closes the series; if a human terminates an unconverged series with a `human-resolution`, automatic resumption for that key is stopped.
152
- - The reviewer returns every P1 it finds in a single call together in `findings[]` (batching). This avoids the serial one-finding-per-round flow that inflated review rounds β€” it does not lower the P1 bar; it just stops deferring already-known P1s to a later round.
153
- - During install, existing `cross-spawn` versions below the verified floor warn by default and fail with `--strict`.
154
- - Approval responses and evidence are kept under `workflow/REQ-.../responses/`.
155
-
156
- In short: **approved changes pass, ambiguous changes stop.**
157
-
158
- ### What It Does *Not* Enforce
159
-
160
- So that you do not miscalculate where your real defenses are:
161
-
162
- - **This is not hard enforcement.** No git hook is installed, so running `git commit` directly instead of `req:commit` bypasses doctor, the approval binding, and the evidence trail. Your real defense for production is still CI and the deployment pipeline.
163
- - **It does not keep your staged content secret.** `req:review-codex` transmits the full `git diff --cached` to Codex (OpenAI), and codex reads the repository root under `--sandbox read-only`. There is no masking, scrubbing, or size cap. For payment or credential-bearing codebases, write a "inspect the staged diff before review" step into your contract (`AGENTS.md`).
164
- - **It does not guarantee anything after the commit.** Approval binds the staged tree at commit time; merge, tag, and publish are each separate control points.
165
-
166
- ---
167
-
168
- ## What Installation Adds
169
-
170
- `npx commitgate init` adds the following to the target project. Existing files are not overwritten by default.
171
-
172
- | Added item | Purpose |
173
- |---|---|
174
- | `workflow/*.schema.json` | Schemas for Codex responses and config |
175
- | `workflow/review-persona.md` | Reviewer persona injected into the Codex review prompt (created only if absent) |
176
- | `req.config.json` | Project-level configuration |
177
- | `AGENTS.md` | The contract (created only if absent) |
178
- | `CLAUDE.md` | Claude Code pointer (created only if absent) |
179
- | `.claude/skills/commitgate/SKILL.md` | Claude Code skill (pointer) |
180
- | `.claude/commands/req.md` | `/req` slash command (pointer) |
181
- | `.cursor/rules/commitgate.mdc` | Cursor rule (pointer) |
182
- | `.claude/skills/commitgate-*/SKILL.md` | **Companion Skills** β€” four of them, see below (existing files preserved) |
183
- | `package.json` scripts | `req:new`Β·`req:next`Β·`req:review-codex`Β·`req:doctor`Β·`req:commit` = `commitgate <verb>` (missing keys only) |
184
-
185
- ### Companion Skills
186
-
187
- CommitGate is a **governance layer** β€” `req:next` computes the next action, and review/approval/evidence gate the commit.
188
- What was missing was **method**: how to sharpen a vague request, how to write the test first, how to corner a bug.
189
- Four skills, adapted from Matt Pocock's public skills (MIT) to fit CommitGate's authority boundaries, ship with it.
190
-
191
- | Skill | When |
192
- |---|---|
193
- | `commitgate-discovery` | **Before** `req:new` β€” turn a vague request into a REQ Brief. **User-invoked** |
194
- | `commitgate-tdd` | When `req:next` returns `AGENT` β€” Red β†’ Green β†’ Refactor β†’ stage |
195
- | `commitgate-diagnosing-bugs` | Bugs, regressions, perf β€” feedback loop β†’ reproduce/minimise β†’ hypothesise β†’ instrument β†’ fix |
196
- | `commitgate-research` | External technology choices β€” primary sources, findings with citations and limits |
197
-
198
- **Auto-discovered, model-invoked.** The harness **discovers** skills automatically, but **the model decides**
199
- whether to use one β€” that is probabilistic, so don't expect a skill to always fire. In Claude Code you can also
200
- invoke one directly with `/commitgate-<name>`. On other harnesses, use whatever invocation that harness offers,
201
- or follow the entry flow in `AGENTS.md`.
202
-
203
- **Suggested flow**: `commitgate-discovery` to sharpen the request β†’ `/req` (Claude Code) or the `AGENTS.md` entry
204
- flow β†’ `req:new` β†’ repeat `req:next`.
205
-
206
- #### Boundaries β€” read this
207
-
208
- - πŸ”΄ **`AGENTS.md` is the contract.** Skills carry **method**, not contract.
209
- Without the skills installed, the **core workflow behaves identically**.
210
- - πŸ”΄ **Skill output is not approval evidence.** Neither a companion skill's output nor the result of running
211
- Matt's external skills separately is **approval evidence** for CommitGate or Codex. Running the review, judging
212
- approval, transitioning state, and committing are **CommitGate's alone**, and `req:next` is the authority on
213
- what comes next.
214
- - Skills are **cooperative text** β€” a skill doesn't block a commit; CommitGate's gate does.
215
-
216
- #### Install, preservation, options
217
-
218
- - **`--no-agent-entrypoints`**: skips the whole `.claude/` layer (including the four companion skills).
219
- - **Existing files preserved (seed-once)**: skills are **meant to be edited**. A skill you modified is
220
- **not overwritten, even with `--force`.** `AGENTS.md`, `CLAUDE.md`, and `workflow/.gitignore` follow the same policy.
221
- - **gitignore warning**: if `.claude/` is gitignored, the skills never reach a teammate's fresh clone.
222
- Install still proceeds, but CommitGate **warns** and tells you how to track them. **`--strict` stops before installing.**
223
- - **Coexists with third-party skills**: third-party `tdd`, `grill-me`, etc. live at `.claude/skills/<name>/`, companions at
224
- `.claude/skills/commitgate-<name>/` β€” **different paths, so neither touches the other.**
225
-
226
- #### Attribution
227
-
228
- Adapted from Matt Pocock's MIT-licensed public skills at baseline SHA `d574778f94cf620fcc8ce741584093bc650a61d3`
229
- and **included as package payload**. CommitGate **does not run or depend on any external skill installer** at
230
- runtime β€” these are pinned copies inside the package. Each SKILL.md carries the full MIT notice; see
231
- `skills/ATTRIBUTION.md` in the package for details.
232
-
233
- ### What it does **not** install
234
-
235
- | Item | Where it lives instead |
236
- |---|---|
237
- | `scripts/req/**` runtime code | `node_modules/commitgate` β€” never copied into your project |
238
- | `tsx` Β· `ajv` Β· `cross-spawn` | runtime dependencies of the `commitgate` package β€” never injected into your `package.json` |
239
-
240
- What stays in your project is **governance and audit data** only: config, contract, schemas, persona, and `workflow/REQ-*` evidence. The **runtime code** lives in the package, so `npm update commitgate` refreshes it with no drift. But the **vendored assets** (schemas, persona) are separate from the runtime β€” on a minor upgrade you must also run `commitgate sync` (see [Upgrading (0.x)](#upgrading-0x)) or the runtime and assets will drift apart.
241
-
242
- The `req:*` scripts call the installed package bin β€” `npm run req:new -- <slug>` β†’ `commitgate req:new <slug>` β†’ `node_modules/.bin/commitgate`.
243
-
244
- The entrypoint files are **thin pointers**. The contract itself lives only in `AGENTS.md`.
245
-
246
- If another tool already owns `.claude/` or `.cursor/`, skip that layer.
247
-
248
- ```sh
249
- npx commitgate --no-agent-entrypoints
250
- ```
251
-
252
- If an `AGENTS.md` already exists without the CommitGate contract marker (`<!-- commitgate:contract -->`), the contract template is installed alongside it as `AGENTS.commitgate.md` and you are told to merge it. Your existing file is never touched.
253
-
254
- Preview without writing files:
255
-
256
- ```sh
257
- npx commitgate --dry-run
258
- ```
259
-
260
- Treat integrity warnings as an install failure:
261
-
262
- ```sh
263
- npx commitgate --strict
264
- ```
265
-
266
- CommitGate stops **before writing any file** if a contract pointer would be swallowed by `.gitignore`, if the `workflow/.gitignore` policy file would not reach a fresh clone, if the working tree makes a safe install commit impossible, or if an existing `cross-spawn` is below the verified floor.
267
-
268
- > `--strict` also treats the `package.json`/lockfile changes left by the required `npm install -D commitgate` as pre-existing dirt. Recommended order: `npm i -D commitgate` β†’ **commit** β†’ `npx commitgate init --strict` β†’ commit the scaffold.
269
-
270
- > `workflow/machine.schema.json` and `workflow/req.config.schema.json` are always copied under `workflow/`, regardless of the `ticketRoot` setting in `req.config.json`.
271
-
272
- ---
273
-
274
- ## Upgrading (0.x)
275
-
276
- Bumping the runtime takes **two** steps β€” `npm update` alone is not enough.
277
-
278
- **β‘  The caret range blocks 0.x minors.** `npm install -D commitgate` writes a `^0.y.z` range. In npm semver,
279
- `^0.7.0` means `>=0.7.0 <0.8.0`, so `npm update`/`pnpm update` **will not cross a 0.x minor** (it stays within 0.7.x).
280
- To cross a minor, raise the range explicitly:
281
-
282
- ```sh
283
- npm install -D commitgate@latest # or a specific version: commitgate@^0.8.0
284
- ```
285
-
286
- **β‘‘ Vendored assets update separately from the runtime.** The command above refreshes the runtime
287
- (`node_modules/commitgate`), but the contract assets in your project's `workflow/`
288
- (`machine.schema.json`, `req.config.schema.json`) **stay as they were**. If you bump the runtime but leave the
289
- assets, the new runtime **reads the old contract**, and newer features (e.g. the full-review escalation of design
290
- delta reviews) are silently disabled. `commitgate sync` restores those assets from the installed package copy:
291
-
292
- ```sh
293
- npx commitgate sync # plan only (dry-run β€” see what would change)
294
- npx commitgate sync --apply # re-sync the schema axis
295
- npx commitgate sync --apply --persona # persona too (restore if missing; your edits are preserved)
296
- ```
297
-
298
- - `sync` restores the **schema axis only** (contracts, always kept current). It does not touch companion skills,
299
- `workflow/.gitignore`, `package.json`, or `req:*`.
300
- - The **persona (`review-persona.md`) is handled only with `--persona`**, and only as a **restore-if-missing**. A
301
- persona you edited yourself is never overwritten (if it differs, it is preserved and only reported) β€” to customize
302
- it, point `reviewPersonaPath` in `req.config.json` at a separate file.
303
- - `req:doctor`'s **D20** WARNs when the vendored schema drifts from the installed copy (it never blocks the commit).
304
-
305
- **β‘’ If you are on an older (vendored) install**, follow up with `migrate` below to move to the Stage B runtime.
306
-
307
- > In short: install `commitgate@latest` β†’ `commitgate sync --apply` β†’ (if needed) `commitgate migrate`.
308
-
309
- ---
310
-
311
- ## Migrating from an older install (`migrate`)
312
-
313
- If `scripts/req/` is copied into your project and `req:*` points at `tsx scripts/req/*.ts`, you have an **older (vendored) install**. `init` detects this and **stops** rather than creating a silent mix, pointing you here.
314
-
315
- ```sh
316
- npm install -D commitgate # first, if it is not a devDependency yet
317
- npx commitgate migrate # plan only β€” writes nothing
318
- npx commitgate migrate --apply # rewrites only the req:* scripts in package.json
319
- ```
320
-
321
- `migrate` does exactly **one** thing: it rewrites the `req:*` keys **whose current value is byte-for-byte the old injected value** to `commitgate <verb>`.
322
-
323
- - **It deletes nothing.** `scripts/req/`, schemas, persona, config, entrypoints, and `workflow/REQ-*` evidence are all left in place. The leftover `scripts/req/` is no longer executed; run `npx commitgate uninstall` to see a cleanup plan first.
324
- - **It never overwrites scripts you edited.** Any value that differs β€” even by one character β€” is treated as yours, preserved, and reported for manual action.
325
- - **It does not commit.** It writes `package.json` only; reviewing is up to you.
326
-
327
- `req:doctor` also reports the install mode (old / current / mixed).
328
-
329
- ---
330
-
331
- ## Support scope
332
-
333
- | Environment | Status |
334
- |---|---|
335
- | **npm** | Fully supported β€” verified on every release by a packed-tarball smoke test |
336
- | **pnpm Β· yarn** (`node_modules` linker) | Supported β€” uses the standard `node_modules/.bin/commitgate` resolution |
337
- | **Yarn PnP** | **Not supported in this release** (untested). Use `nodeLinker: node-modules` |
338
- | **workspaces / monorepo** | **Workspace-root installs** are supported (`req.config.json` and `workflow/` at the root). Installing independently in a sub-package is not supported |
339
-
340
- **Reproducibility**: the review model/effort pins in `req.config.json`, plus the schemas and persona, stay in your project, so past review inputs are reproducible from git history. Runtime versions are pinned by your lockfile β€” **commit `package-lock.json`** (or the pnpm/yarn equivalent).
341
-
342
- ### Companion Skills discovery scope
343
-
344
- **Installation is identical everywhere.** What follows is about whether a harness **discovers** those files.
345
-
346
- | harness | Discovery |
347
- |---|---|
348
- | **Claude Code** | Reads `.claude/skills/<name>/SKILL.md` natively |
349
- | **Cursor (editor)** | Reads `.claude/skills` as a compatibility path |
350
- | **Cursor (CLI)** | ⚠️ **May differ by version and run mode β€” not guaranteed** |
351
- | **Codex** | **Out of product scope** β€” no companion entrypoint is installed. In CommitGate, Codex is the **Reviewer**; these four are **Builder aids** |
352
-
353
- ⚠️ **This is based on vendor primary documentation β€” the CommitGate team did not verify it empirically.**
354
- Checked **2026-07-17** on win32 x64 / Node v20.19.5. If a vendor changes behaviour, this table goes stale.
355
-
356
- ⚠️ **We do not claim Cursor CLI is either supported or unsupported.** Cursor announced Agent Skills for both
357
- editor and CLI, but discovery via the `.claude/skills` compatibility path is reported to differ by version and
358
- run mode, and we could not verify it. If discovery doesn't happen, **the core workflow is unaffected** β€” skills
359
- are a quality aid, and `AGENTS.md` is the contract.
360
-
361
- We do **not** double-install into `.cursor/skills` to work around this: that path's CLI behaviour is also
362
- uncertain, and the same content in two places invites drift. If the vendor fixes it, it works **with no change
363
- on our side** β€” same path.
364
-
365
- ---
366
-
367
- ## Removing CommitGate
368
-
369
- CommitGate lives in two places: the **runtime** (`node_modules/commitgate`) and the **governance files installed into your project**.
370
-
371
- The package manager removes the runtime:
372
-
373
- ```sh
374
- npm uninstall -D commitgate # pnpm remove -D commitgate Β· yarn remove commitgate
375
- ```
376
-
377
- For the project files, review the plan below and clean up yourself. First, the important part: **`npx commitgate` is not a global install.** npx downloads the package into the npm cache (`_npx/<hash>/`) and runs it once; it leaves nothing in your global `node_modules` and nothing on your PATH.
378
-
379
- Start by previewing the removal plan. This command **deletes nothing**:
380
-
381
- ```sh
382
- npx commitgate uninstall
383
- ```
384
-
385
- It reads your repo and classifies what it finds: (1) CommitGate-owned files that are byte-identical to the package originals, (2) files that differ and need your review, (3) files that must not be removed automatically, and (4) audit evidence. Then it prints the revert commands that match your commit state. You review them and run the deletions yourself.
386
-
387
- ### Why isn't removal automatic?
388
-
389
- `init` **does not record on disk what it created.** At removal time it is therefore impossible to tell apart:
390
-
391
- - `AGENTS.md` is created **only when absent**. If you already had one, init leaves it alone β€” so a file init wrote and a file you wrote look identical on disk.
392
- - `req.config.json` is **merged** (missing keys only) when it already exists. The original is not kept, so the merge cannot be undone.
393
- - `package.json` only gets keys that are **absent**. A pre-existing `req:doctor` or `cross-spawn` is not CommitGate's. And `ajv`, `cross-spawn`, and `tsx` are devDependencies other packages commonly use too.
394
- - Your `ticketRoot` (default `workflow/`) accumulates REQ ticket `state.json` and `approvals.jsonl` β€” this tool's **audit evidence**.
395
-
396
- Deleting all of that without a ledger would destroy user data. CommitGate installs no git hooks and touches no git config β€” it is a pure in-tree scaffolder, so git is the source of truth for undoing it.
397
-
398
- ### If you have not committed the scaffold
399
-
400
- ```sh
401
- git status --porcelain -uall # see what was added
402
- git diff -- package.json # see the injected req:* scripts and devDependencies
403
- ```
404
-
405
- Then revert it yourself. Always restore `package.json` from `HEAD`:
406
-
407
- ```sh
408
- git checkout HEAD -- package.json
409
- ```
410
-
411
- > ⚠️ Without `HEAD`, git restores from the **index**, so after a `git add` the injected `req:*` scripts survive.
412
- > ⚠️ This command also discards **any other uncommitted edits** to `package.json`. Check the diff first.
413
-
414
- Delete only the paths `npx commitgate uninstall` listed. Removing `scripts/req/` or `workflow/` as whole directories would also take your own files and your ticket evidence with them.
415
-
416
- > git does not track empty directories. After deleting the files, `git status` can report a clean tree while empty `scripts/`, `workflow/`, `.claude/`, and `.cursor/` directories remain on disk.
417
-
418
- ### If you already committed the scaffold
419
-
420
- Revert the commit that introduced it.
421
-
422
- ```sh
423
- git log --diff-filter=A --format='%H %s' -- scripts/req/req-new.ts
424
- git revert <sha>
425
- ```
426
-
427
- `npx commitgate uninstall` finds the introducing commit for you. If that commit also contains unrelated work, reverting it undoes that work too β€” inspect it with `git show <sha>` first. If the scaffold was introduced across several commits, no single revert will undo it.
428
-
429
- ### Clearing the npx cache (unrelated to your repo)
430
-
431
- Check for a global install first:
432
-
433
- ```sh
434
- npm ls -g commitgate # empty output means it is not installed globally
435
- npm uninstall -g commitgate # only if you did install it globally
436
- ```
437
-
438
- The package npx downloaded stays under `_npx/` in the npm cache.
439
-
440
- ```powershell
441
- # Windows (PowerShell)
442
- Remove-Item -Recurse -Force "$(npm config get cache)\_npx"
443
- ```
444
-
445
- ```sh
446
- # macOS / Linux
447
- rm -rf "$(npm config get cache)/_npx"
448
- ```
449
-
450
- > ⚠️ **`npm cache clean --force` is not a CommitGate removal command.** It empties `_cacache` only and leaves `_npx` intact. It has nothing to do with the scaffolding in your repo.
451
-
452
- ---
453
-
454
- ## Prerequisites
455
-
456
- | Requirement | Check | Notes |
457
- |---|---|---|
458
- | Git | `git --version` | Required |
459
- | Node.js 18.17+ | `node --version` | Required |
460
- | npm, pnpm, or yarn | `npm --version` | Examples use npm |
461
- | Codex CLI | `codex --version` | Required for review runs |
462
-
463
- If Codex CLI is not installed:
464
-
465
- ```sh
466
- npm install -g @openai/codex
467
- codex login
468
- codex login status
469
- ```
470
-
471
- On Windows, if `codex` is not found right after installation, open a new terminal so PATH is reloaded.
472
-
473
- ---
474
-
475
- ## Manual Commands
476
-
477
- Most users should use the prompt flow above. This section is for understanding what the workflow runs internally or for debugging.
478
-
479
- ```sh
480
- # 1. Create a ticket and branch
481
- npm run req:new -- my-feature --run
482
-
483
- # 2. Write design docs, then stage them
484
- git add workflow/REQ-2026-001/00-requirement.md workflow/REQ-2026-001/01-design.md workflow/REQ-2026-001/02-plan.md
485
-
486
- # 3. Design review
487
- npm run req:review-codex -- 2026-001 --kind design --run
488
-
489
- # 4. Implement code, then stage source files
490
- git add <changed-source-files>
491
-
492
- # 5. Gate check
493
- npm run req:doctor -- 2026-001
494
-
495
- # 6. Implementation review
496
- npm run req:review-codex -- 2026-001 --kind phase --run
497
-
498
- # 7. Commit approved code
499
- npm run req:commit -- 2026-001 --run -m "feat: my feature"
500
- ```
501
-
502
- Important: only stage code and documents you authored for the source commit. `state.json` and `responses/` are managed by the tool.
503
-
504
- For multi-line commit messages, use a file instead of `-m`.
505
-
506
- ```sh
507
- npm run req:commit -- 2026-001 --run --message-file commit-message.txt
508
- ```
509
-
510
- ---
511
-
512
- ## Command Cheat Sheet
513
-
514
- | Command | Purpose |
515
- |---|---|
516
- | `npm install -D commitgate` | **Install the runtime (required first)** β€” the executable code lives in `node_modules/commitgate` |
517
- | `npx commitgate init` | Install config, contract, schemas, and the `req:*` scripts into a project |
518
- | `npx commitgate init --dry-run` | Preview the install plan without writing files |
519
- | `npx commitgate init --strict` | Treat integrity warnings as install failures β€” stops before writing any file |
520
- | `npx commitgate init --no-agent-entrypoints` | Skip `.claude/`, `.cursor/`, and `CLAUDE.md` |
521
- | `npx commitgate sync [--apply] [--persona]` | Re-sync vendored **schema-axis** assets (machine/req.config schema) to the installed package copy after an upgrade (plan-only by default). `--persona` **restores a missing persona only** (never overwrites your edits). See [Upgrading (0.x)](#upgrading-0x) |
522
- | `npx commitgate migrate [--apply]` | Move an older vendored install to the runtime package (plan-only by default, non-destructive) |
523
- | `npx commitgate uninstall` | Preview the removal plan (read-only β€” deletes nothing) |
524
- | `npm uninstall -D commitgate` | Remove the runtime |
525
- | `npm run req:new -- <slug> --run [--successor-of <REQ-id>]` | Create a REQ ticket, branch, and design docs. `--successor-of` creates a replacement REQ (see below) |
526
- | `npm run req:next -- <id> [--json]` | **Compute the next action** (read-only) |
527
- | `npm run req:review-codex -- <id> --kind design --run` | Review the design |
528
- | `npm run req:review-codex -- <id> --kind phase --phase <p> --run` | Review the implementation |
529
- | `npm run req:doctor -- <id>` | Check gate status |
530
- | `npm run req:commit -- <id> --run -m "message"` | Commit approved changes |
531
-
532
- `req:*` are **`package.json` scripts**, not executables on your PATH. npm needs the `--` separator to pass arguments.
533
-
534
- ```sh
535
- npm run req:next -- 2026-002 # npm
536
- pnpm req:next 2026-002 # pnpm
537
- yarn req:next 2026-002 # yarn
538
- ```
539
-
540
- **Replacement REQ (`--successor-of`)**: only when a human has terminated a review series with a `human-resolution` **replace** decision can you create a replacement REQ that preserves the parent's lineage (total attempts and the resolution record) via `req:new --successor-of <REQ-id>`. If the parent has no valid replace resolution, ticket creation fails closed β€” this does not block ordinary new-REQ creation.
541
-
542
- ---
543
-
544
- ## Configuration
545
-
546
- Defaults are enough for most projects. If needed, edit `req.config.json` in the project root.
547
-
548
- | Key | Default | Meaning |
549
- |---|---|---|
550
- | `branchPrefix` | `"feat/req-"` | Prefix for new branches |
551
- | `ticketRoot` | `"workflow"` | REQ ticket directory |
552
- | `packageManager` | auto-detected | `npm`, `pnpm`, or `yarn` |
553
- | `designDocs` | `00/01/02` docs | Design document filenames |
554
- | `reviewPersonaPath` | `"workflow/review-persona.md"` | First block of the review prompt. `null` disables it β€” but delta design reviews still inject the built-in delta contract |
555
- | `reviewModel` | `"gpt-5.6-terra"` | codex review model (pinned via `-c model=`). `null` inherits your global codex config |
556
- | `reviewReasoningEffort` | `"high"` | codex review reasoning effort. One of `none`, `minimal`, `low`, `medium`, `high`, `xhigh`. `null` inherits the global setting |
557
- | `reviewBudget` | `{ "autoBudget": 5, "hardCap": 8 }` | Re-review attempt budget for an open `(review_kind, phase_id)` review series. With the defaults, rounds 1–5 run automatically, rounds 6–8 each require a human exception record bound to that series and round, and once `hardCap` is spent the next attempt (round 9 onward) is blocked even with an exception. `hardCap ≀ 8`, `autoBudget ≀ hardCap` |
558
- | `phaseCommit` | `{ "autoApprove": "never" }` | Per-phase auto-commit policy. `never` (default) stops for a human before every phase commit (current behavior). `low-only` auto-commits Codex-approved phases of **LOW-risk** tickets without a human stop and moves the single human confirmation to just before the feature→main merge. HIGH-risk tickets still stop at every phase under any value (`userConfirmGate` backstop). There is no `"all"` value (it would livelock on HIGH) |
559
-
560
- Empty `branchPrefix` values and paths that escape the project root are rejected.
561
-
562
- **Pinned review model & effort**: `req:review-codex` injects `-c model=` and `-c model_reasoning_effort=` into the codex arguments to **pin the model and reasoning effort**. Without pinning, a review inherits your global `~/.codex/config.toml` (e.g. `model_reasoning_effort="ultra"`), making a single review take minutes and burn tokens. The defaults are `gpt-5.6-terra`/`high`; if your codex doesn't support that model, change it in `req.config.json` or set it to `null` to inherit the global config. Whether the overrides are actually honored can be checked with `npm run verify:overrides` (requires the codex CLI).
563
-
564
- **Stateless re-reviews**: each re-review starts a **fresh codex thread** (it does not resume/accumulate the prior conversation β€” which drove token growth and goalpost drift). Only the previous same-target NEEDS_FIX findings are carried into the prompt as reference data, to confirm closure.
565
-
566
- ---
567
-
568
- ## FAQ
569
-
570
- **What happens if Codex CLI is missing?**
571
- The review command fails. It is not treated as approval.
572
-
573
- **Can I edit code after approval and still commit?**
574
- No. If the staged tree changes after approval, CommitGate treats the approval as stale and requires review again.
575
-
576
- **Why should I not stage `state.json` or `responses/`?**
577
- They are workflow state and evidence files. Mixing them into the source commit weakens the approval binding, so `req:commit` blocks it.
578
-
579
- **What should I do if I see a cross-spawn version warning?**
580
- It means the target project may already have a `cross-spawn` version below CommitGate's verified floor. Upgrade it with `npm i -D cross-spawn@^7.0.6`. In CI or security-sensitive installs, use `npx commitgate --strict` to treat the warning as a failure.
581
-
582
- **Does running install twice overwrite files?**
583
- No. Existing files are skipped. Use `--force` if you intentionally want to refresh them.
584
-
585
- ---
586
-
587
- ## Current Scope
588
-
589
- The current release is a **runtime package model**. Executable code and runtime dependencies live only in `node_modules/commitgate`; your project keeps governance/audit data and the `req:* = commitgate <verb>` scripts. (Older vendored installs move over with [`migrate`](#migrating-from-an-older-install-migrate).)
590
-
591
- Current verification:
592
-
593
- - GitHub Actions runs a `ubuntu-latest`, `macos-latest`, `windows-latest` Γ— Node 18/20/22 matrix.
594
- - `npm run smoke` installs the packed tarball into a throwaway project and asserts that the target has **no** `scripts/req/`, that `tsx`/`ajv`/`cross-spawn` are **not** injected, that all five `req:*` scripts point at the package bin, and that `npm run req:doctor` actually dispatches into the module inside the package. It verifies `migrate`'s non-destructiveness the same way.
595
- - A Windows `.cmd` wrapper injection regression test protects package-manager and Codex wrapper paths.
596
-
597
- Future scope:
598
-
599
- - Yarn PnP support; independent installs in workspace sub-packages
600
- - Asset↔runtime version drift detection
601
- - Non-git VCS support
602
- - More design document templates
603
-
604
- ---
605
-
606
- ## License
607
-
608
- [MIT](./LICENSE) Β© 2026 sol5288
1
+ # CommitGate
2
+
3
+ 🌐 [ν•œκ΅­μ–΄](./README.md) Β· **English**
4
+
5
+ **A commit gate that blocks AI-generated code from being committed until Codex has reviewed and approved it.**
6
+
7
+ [![CI](https://github.com/sol5288/commitgate/actions/workflows/ci.yml/badge.svg)](https://github.com/sol5288/commitgate/actions/workflows/ci.yml)
8
+ [![npm version](https://img.shields.io/npm/v/commitgate.svg)](https://www.npmjs.com/package/commitgate)
9
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
10
+
11
+ AI coding agents can move quickly, but unreviewed changes should not go straight into your history. CommitGate wraps each change in a REQ ticket and only lets **the staged tree Codex approved** be committed. If the code changes after approval, or if evidence is missing, it fails closed by default.
12
+
13
+ ## What it blocks
14
+
15
+ - πŸ”’ **Nothing is committed without an approved Codex review.** If the review fails or is absent, `req:commit` does not let it through.
16
+ - πŸ” **A staged change that moves after approval is re-reviewed.** If the approved tree differs from the tree you are about to commit, it is blocked as stale.
17
+ - 🧯 **When in doubt, it fails closed.** A no-findings-but-unapproved response, or a missing/failing Codex CLI, never passes silently.
18
+
19
+ For the full list of what is and is not guaranteed, see **[Guarantees & limits](https://github.com/sol5288/commitgate/blob/main/docs/guarantees.en.md)**.
20
+
21
+ ## ⚠️ Before you start
22
+
23
+ - **Review sends your staged diff in full to an external service (Codex/OpenAI).** `req:review-codex` transmits the entire `git diff --cached`, and Codex reads your repository root under `--sandbox read-only`, so files outside the diff can be read too. There is **no** masking, filtering, or size cap β€” check the staged content for credentials, tokens, and personal data before running a review.
24
+ - **No git hook is installed β€” the gate can be bypassed.** Running `git commit` directly instead of `req:commit` bypasses the gate, the approval binding, and the evidence trail. Enforcement keeps a **cooperating agent on the contract's rails**; it is not a physical barrier against a human going around it.
25
+
26
+ ## Get started in 3 minutes
27
+
28
+ From a folder that is a git repository with a `package.json`, two steps:
29
+
30
+ ```sh
31
+ npm install -D commitgate # 1) install the runtime β€” the executable code lives in node_modules/commitgate
32
+ npx commitgate init # 2) add config, contract, schemas + the req:* scripts to your project
33
+ ```
34
+
35
+ Installation writes files but **does not commit** them. `req:new` requires a clean working tree, so commit the scaffold first β€” the installer's `λ‹€μŒ:` (next steps) output prints the exact paths to stage (do not stage everything with `-A`/`.`). For prerequisites (Codex CLI, etc.), pathspec staging, and the full first flow, see **[Quick Start](https://github.com/sol5288/commitgate/blob/main/docs/quick-start.en.md)**.
36
+
37
+ Then just give the agent a requirement.
38
+
39
+ ```text
40
+ /req Add a profile edit API
41
+
42
+ - What: PATCH /profile to edit nickname and bio
43
+ - Why: there is currently no way to change a profile after signup
44
+ - Constraints: reuse the existing auth middleware, no schema changes
45
+ - Done when: unit tests pass, unauthorized users get 403
46
+ ```
47
+
48
+ The first response usually sets up the ticket, branch, phase plan, and control points.
49
+
50
+ ```text
51
+ REQ-2026-002 issued
52
+ branch: feat/req-2026-002-profile-edit-api
53
+ phases:
54
+ - phase-1: implement PATCH /profile
55
+ - phase-2: tests and regression check
56
+ control point: before req:commit --run / [B1] before a main direct push (or [I1] open PR β†’ [I2] merge)
57
+ ```
58
+
59
+ The agent then follows whatever `req:next` says β€” **design β†’ Codex review β†’ implement β†’ re-review β†’ commit**. You only step in at a control point (`AWAIT_HUMAN`) to give an approval sentence. (Outside Claude Code, a plain requirement works without `/req` β€” `AGENTS.md` and `.cursor/rules` load the rules.)
60
+
61
+ ## How it works
62
+
63
+ `req:new` creates the ticket, branch, and design docs, and the next action at every step is always **computed** by `req:next` from `state.json` and git state (read-only β€” the agent does not guess).
64
+
65
+ ```text
66
+ req:new β†’ design review β†’ implement β†’ phase review β†’ approval β†’ req:commit β†’ (integration & release are separate control points)
67
+ ```
68
+
69
+ For the loop details, the `kind` table, the reviewer persona, and delta re-reviews, see **[Workflow](https://github.com/sol5288/commitgate/blob/main/docs/workflow.en.md)**; for agent entrypoints, passing a requirement, and companion skills, see the **[Agent guide](https://github.com/sol5288/commitgate/blob/main/docs/agent-prompt.en.md)**.
70
+
71
+ ## Common commands
72
+
73
+ | Command | Purpose |
74
+ |---|---|
75
+ | `npm run req:new -- <slug> --run` | Create the REQ ticket, branch, and design docs |
76
+ | `npm run req:next -- <id>` | **Compute the next action** (read-only) |
77
+ | `npm run req:doctor -- <id>` | Check gate status |
78
+ | `npm run req:commit -- <id> --run -m "..."` | Commit the approved change |
79
+
80
+ `req:*` are `package.json` scripts, not PATH executables (npm needs `--` to pass arguments). The full command set and `pnpm`/`yarn` forms are in **[Workflow](https://github.com/sol5288/commitgate/blob/main/docs/workflow.en.md)**.
81
+
82
+ ## Learn more
83
+
84
+ | Doc | Contents |
85
+ |---|---|
86
+ | [Quick Start](https://github.com/sol5288/commitgate/blob/main/docs/quick-start.en.md) | Install, prerequisites, first run |
87
+ | [Workflow](https://github.com/sol5288/commitgate/blob/main/docs/workflow.en.md) | `req:next` loop, kinds, persona, commands |
88
+ | [Agent guide](https://github.com/sol5288/commitgate/blob/main/docs/agent-prompt.en.md) | Entrypoints, passing a requirement, companion skills |
89
+ | [Guarantees & limits](https://github.com/sol5288/commitgate/blob/main/docs/guarantees.en.md) | Safety contract, support scope |
90
+ | [Configuration](https://github.com/sol5288/commitgate/blob/main/docs/configuration.en.md) | `req.config.json` |
91
+ | [Upgrading (0.x)](https://github.com/sol5288/commitgate/blob/main/docs/upgrade.en.md) | Runtime updates, `sync`, `quickstart`, `migrate` |
92
+ | [Removing](https://github.com/sol5288/commitgate/blob/main/docs/uninstall.en.md) | Safe removal procedure |
93
+ | [Troubleshooting](https://github.com/sol5288/commitgate/blob/main/docs/troubleshooting.en.md) | FAQ |
94
+ | [Development & scope](https://github.com/sol5288/commitgate/blob/main/docs/development.en.md) | CI, verification, roadmap |
95
+
96
+ ## License
97
+
98
+ [MIT](./LICENSE) Β© 2026 sol5288