coderifts 4.6.0 → 4.8.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/CHANGELOG.md +66 -0
- package/README.md +71 -5
- package/bin/coderifts.js +7 -2
- package/dist/cli.js +793 -76
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,71 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.8.0
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **VS Code / Copilot PreToolUse camelCase (DRIFT 1).** VS Code Agent hooks
|
|
7
|
+
pass `toolName` / `toolInput` / `filePath` (and `targetFile`). The hook
|
|
8
|
+
already tolerated `toolName`/`toolInput` but missed several property
|
|
9
|
+
aliases, so flattened camelCase payloads and `targetFile` were refused as
|
|
10
|
+
unparseable (fail-closed, safe, unusable). Every Claude-shaped read site
|
|
11
|
+
now accepts snake_case and camelCase: `tool_name`/`toolName`,
|
|
12
|
+
`tool_input`/`toolInput`, `file_path`/`filePath`/`path`/`target_file`/`targetFile`,
|
|
13
|
+
`content`/`contents`. Snake_case behaviour is unchanged. Garbage is still
|
|
14
|
+
fail-closed.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **Matcher-inert hosts (DRIFT 2, documented, not a host fix).** VS Code
|
|
18
|
+
parses hook matchers but does not apply them — the hook fires on every
|
|
19
|
+
tool call. Non-Write/Edit/MultiEdit tools now exit **0** silently with no
|
|
20
|
+
network and **without requiring an API key** (parse → skip → key, so a
|
|
21
|
+
missing key cannot brick Read/Bash). Non-contract Write paths skip before
|
|
22
|
+
the key gate too. Garbage is still fail-closed (`stdin_unparseable`).
|
|
23
|
+
Spec-path Write/Edit/MultiEdit without a key is still fail-closed.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- **`copilot` MCP host (DRIFT 3).** `MCP_HOSTS` grows a third entry:
|
|
27
|
+
`.vscode/mcp.json`, root key **`servers`** (not `mcpServers`),
|
|
28
|
+
`type: "http"` + `url`. The writer special-cases the root key; Claude and
|
|
29
|
+
Cursor stay on `mcpServers`. `coderifts init --agents --hosts` accepts
|
|
30
|
+
`copilot` and includes it in `all`. Merge preserves other `servers` (and
|
|
31
|
+
any leftover keys). `--check` uses the same predicate.
|
|
32
|
+
- README Copilot section: `hook install --claude` arms VS Code agent mode
|
|
33
|
+
(measured), matcher-inert behaviour, honest boundary (hooks gate the
|
|
34
|
+
agent, not the human; inline completions are not tool calls).
|
|
35
|
+
|
|
36
|
+
## 4.7.0
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
- **`coderifts enforce --check`** — provider-native CD enforcement evidence.
|
|
40
|
+
Queries GitHub (and local workflow files) and reports, per layer,
|
|
41
|
+
`VERIFIED` / `NOT_VERIFIED` / `UNVERIFIABLE(reason)`:
|
|
42
|
+
1. required check `CodeRifts / contract-gate` on default-branch protection
|
|
43
|
+
2. `enforce_admins` (admin bypass)
|
|
44
|
+
3. `required_status_checks.strict`
|
|
45
|
+
4. GitHub Environment protection rules (`--env`)
|
|
46
|
+
5. workflow references `coderifts/contract-gate@v0` (local)
|
|
47
|
+
6. workflow runs `coderifts deploy-gate` (local)
|
|
48
|
+
|
|
49
|
+
`inescapable_deploy` is **true only when every layer is VERIFIED**. Otherwise
|
|
50
|
+
the field stays false and the JSON carries the queried facts. `--json`
|
|
51
|
+
includes each layer's status, the API endpoint consulted, and `queried_at`.
|
|
52
|
+
|
|
53
|
+
Auth: `GITHUB_TOKEN` / `GH_TOKEN` (user). App installation token
|
|
54
|
+
(`GITHUB_APP_TOKEN`) is accepted but **cannot** query branch protection —
|
|
55
|
+
the GitHub App permission set is contents:read, pull_requests, checks
|
|
56
|
+
(AUDIT.md §2.4); `GET .../protection` needs `administration:read`. No
|
|
57
|
+
token → `UNVERIFIABLE` with the exact instruction. Token values are never
|
|
58
|
+
printed. GitLab/Bitbucket: no adapter (UNVERIFIABLE, never stubbed).
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
- **`observeCDEnforcement`:** `CODERIFTS_DEPLOY_NO_BYPASS` is recorded as
|
|
62
|
+
`host_claim_no_bypass` and no longer sets `bypass_possible: false`.
|
|
63
|
+
`--enforce` still marks the step ENFORCING (exit is already fail-closed)
|
|
64
|
+
but is a **host claim**. `bypass_possible` is false only when
|
|
65
|
+
`providerEvidence.inescapable_deploy === true` from `enforce --check`.
|
|
66
|
+
Guard `deployGate` still consumes `{ enforcement, bypass_possible }` — the
|
|
67
|
+
CLI must not pass a flag-derived “no bypass”.
|
|
68
|
+
|
|
3
69
|
## 4.6.0
|
|
4
70
|
|
|
5
71
|
**Version pick:** the parallel Cursor-hook round claimed **4.5.0**
|
package/README.md
CHANGED
|
@@ -72,6 +72,7 @@ coderifts init --agents # all hosts, all four pieces
|
|
|
72
72
|
coderifts init --agents --dry-run # plan only — writes nothing
|
|
73
73
|
coderifts init --agents --hosts=claude # Claude Code only
|
|
74
74
|
coderifts init --agents --hosts=cursor # Cursor only
|
|
75
|
+
coderifts init --agents --hosts=copilot # GitHub Copilot / VS Code only
|
|
75
76
|
coderifts init --agents --no-hook # skip host hook install
|
|
76
77
|
coderifts init --agents --no-workflow # skip .github/workflows/coderifts.yml
|
|
77
78
|
coderifts init --agents --check # which of the four pieces are present
|
|
@@ -79,9 +80,9 @@ coderifts init --agents --check # which of the four pieces are present
|
|
|
79
80
|
|
|
80
81
|
| Piece | What it writes | Host-specific shape |
|
|
81
82
|
|-------|----------------|---------------------|
|
|
82
|
-
| **MCP config** | `.mcp.json` (Claude Code), `.cursor/mcp.json` (Cursor) |
|
|
83
|
-
| **Agent rules** | generated host files via `agent-setup`'s writer | `AGENTS.md` is always written. Claude also gets `CLAUDE.md`; Cursor also gets `.cursor/rules/coderifts.mdc`. `--hosts=all` adds
|
|
84
|
-
| **Host hook** | `.claude/settings.json`, `.cursor/hooks.json` | Reuses `hook install --claude` / `--cursor` (JSON-merge, backup, idempotent) |
|
|
83
|
+
| **MCP config** | `.mcp.json` (Claude Code), `.cursor/mcp.json` (Cursor), `.vscode/mcp.json` (Copilot / VS Code) | Three shapes, never normalised into one: Claude `mcpServers` + `type: "http"` + `url`; Cursor `mcpServers` + `url` only (no `type`); Copilot **`servers`** (not `mcpServers`) + `type: "http"` + `url`. Never `httpUrl` (that is Gemini, extension-level — this command does not write it). |
|
|
84
|
+
| **Agent rules** | generated host files via `agent-setup`'s writer | `AGENTS.md` is always written. Claude also gets `CLAUDE.md`; Cursor also gets `.cursor/rules/coderifts.mdc`; Copilot also gets `.github/copilot-instructions.md`. `--hosts=all` adds LangGraph and OpenAI instructions. (`coderifts init agent` is a different command — it writes a `.coderifts.yml` template.) |
|
|
85
|
+
| **Host hook** | `.claude/settings.json`, `.cursor/hooks.json` | Reuses `hook install --claude` / `--cursor` (JSON-merge, backup, idempotent). Copilot shares Claude's `.claude/settings.json` — VS Code reads it by default. |
|
|
85
86
|
| **CI workflow** | `.github/workflows/coderifts.yml` | `coderifts/contract-gate@v0`. `require-verified-monitoring` is commented (honest default: **false**) |
|
|
86
87
|
|
|
87
88
|
**Next manual step:** add `CODERIFTS_API_KEY` to the repository secrets. The
|
|
@@ -168,8 +169,11 @@ gate reason + `renderDecisionWhy` when a body exists) and
|
|
|
168
169
|
unsigned file still prints the unsigned-receipt truth loudly.
|
|
169
170
|
|
|
170
171
|
**`--enforce` / `CODERIFTS_DEPLOY_ENFORCE=true`:** accepted silently (no-op
|
|
171
|
-
for exit — default is already fail-closed).
|
|
172
|
-
`inescapable_deploy
|
|
172
|
+
for exit — default is already fail-closed). This is a **host claim** that the
|
|
173
|
+
step is ENFORCING. It does **not** set `inescapable_deploy`. That field is
|
|
174
|
+
true only from queried pipeline protection (`coderifts enforce --check`).
|
|
175
|
+
`CODERIFTS_DEPLOY_NO_BYPASS` is recorded as a host claim and does not clear
|
|
176
|
+
`bypass_possible`.
|
|
173
177
|
|
|
174
178
|
**Infra vs policy:** missing `--env` / `--artifact`, malformed receipt JSON, or
|
|
175
179
|
an unreachable `--keys` registry prints distinct `INFRA` wording plus
|
|
@@ -344,6 +348,37 @@ weakened by `CODERIFTS_ADVISORY`.
|
|
|
344
348
|
CODERIFTS_ADVISORY=1 coderifts claude-hook
|
|
345
349
|
```
|
|
346
350
|
|
|
351
|
+
### GitHub Copilot / VS Code agent mode
|
|
352
|
+
|
|
353
|
+
Measured (VS Code **1.110**, Agent hooks Preview, 2026-08-24): VS Code **reads
|
|
354
|
+
`.claude/settings.json` by default**. `coderifts hook install --claude`
|
|
355
|
+
therefore arms Copilot agent mode — there is no separate `--copilot` hook
|
|
356
|
+
installer. VS Code Agent hooks **are deny-capable**: PreToolUse honours
|
|
357
|
+
`permissionDecision` allow|deny|ask and **exit 2**.
|
|
358
|
+
|
|
359
|
+
**Property names (CLI 4.8.0):** VS Code passes camelCase (`toolName` /
|
|
360
|
+
`toolInput` / `filePath` / `targetFile`). The hook accepts those alongside
|
|
361
|
+
Claude's snake_case (`tool_name` / `tool_input` / `file_path`). Flattened
|
|
362
|
+
payloads (path on the root object) are accepted. Garbage input is still
|
|
363
|
+
fail-closed.
|
|
364
|
+
|
|
365
|
+
**Matcher limitation (host behaviour, not a CLI bug):** VS Code **parses** hook
|
|
366
|
+
matchers (`Write|Edit|MultiEdit`) but **does not apply them**. The hook fires
|
|
367
|
+
on every tool call. Non-governed tools (Read, Bash, …) and non-contract paths
|
|
368
|
+
exit **0** silently with **no network** and **no API key required** — cheap
|
|
369
|
+
and fail-open for anything that is not a Write/Edit/MultiEdit of the spec. It
|
|
370
|
+
is noisy (every tool call invokes the process) and safe (irrelevant tools are
|
|
371
|
+
not blocked). A spec-path write without a key is still fail-closed.
|
|
372
|
+
|
|
373
|
+
**Honest boundary:** hooks gate the **agent**, not the human. Inline
|
|
374
|
+
completions (ghost text) are not tool calls and are not governed. A developer
|
|
375
|
+
typing in the editor is not a PreToolUse event.
|
|
376
|
+
|
|
377
|
+
**MCP:** `coderifts init --agents` (and `--hosts=copilot`) writes
|
|
378
|
+
`.vscode/mcp.json` with root key **`servers`** — a third shape. Claude Code and
|
|
379
|
+
Cursor use `mcpServers`; Copilot cloud Settings paste also uses `mcpServers`.
|
|
380
|
+
Do not copy one file onto another host.
|
|
381
|
+
|
|
347
382
|
### `coderifts status [repo]`
|
|
348
383
|
|
|
349
384
|
**Read-only** cross-layer enforcement report (Runtime / Merge / Deploy, plus
|
|
@@ -382,13 +417,44 @@ failed, **1** on missing repo/key, API error, or any apply failure.
|
|
|
382
417
|
|------|-------------|---------|
|
|
383
418
|
| `[repo]` / `--repo <owner/repo>` | Repository | none (required) |
|
|
384
419
|
| `--apply` | Run underlying setup commands | dry-run |
|
|
420
|
+
| `--check` | Query GitHub + local workflows (read-only evidence) | `false` |
|
|
421
|
+
| `--env <name>` | With `--check`: GitHub Environment to query | none |
|
|
422
|
+
| `--branch <name>` | With `--check`: branch (default: repo default) | default branch |
|
|
385
423
|
| `--json` | Machine-readable JSON result | `false` |
|
|
386
424
|
|
|
387
425
|
```bash
|
|
388
426
|
coderifts enforce owner/repo
|
|
389
427
|
coderifts enforce --repo owner/repo --apply
|
|
428
|
+
coderifts enforce --check --repo owner/repo --env production --json
|
|
390
429
|
```
|
|
391
430
|
|
|
431
|
+
### `coderifts enforce --check`
|
|
432
|
+
|
|
433
|
+
Provider-native pipeline-protection evidence. This is **not** a host claim:
|
|
434
|
+
`--enforce` and `CODERIFTS_DEPLOY_NO_BYPASS` do **not** set
|
|
435
|
+
`inescapable_deploy`. The field is true only when every layer below is
|
|
436
|
+
`VERIFIED`.
|
|
437
|
+
|
|
438
|
+
| Layer | VERIFIED when |
|
|
439
|
+
|-------|----------------|
|
|
440
|
+
| `required_check` | Default-branch protection requires `CodeRifts / contract-gate` |
|
|
441
|
+
| `enforce_admins` | `enforce_admins.enabled` is **true** (admins cannot bypass). `false` = NOT_VERIFIED (admin bypass open) |
|
|
442
|
+
| `strict_status_checks` | `required_status_checks.strict` is true |
|
|
443
|
+
| `environment_protection` | `--env` names a GitHub Environment with protection rules or a deployment branch policy |
|
|
444
|
+
| `workflow_contract_gate` | a local `.github/workflows` file references `coderifts/contract-gate@v0` |
|
|
445
|
+
| `workflow_deploy_gate` | a local workflow runs `coderifts deploy-gate` |
|
|
446
|
+
|
|
447
|
+
Statuses: `VERIFIED` / `NOT_VERIFIED` / `UNVERIFIABLE(reason)`. Auth:
|
|
448
|
+
`GITHUB_TOKEN` (never printed). **No token** → API layers `UNVERIFIABLE` with
|
|
449
|
+
the instruction to set `GITHUB_TOKEN` (repo + `administration:read`). The
|
|
450
|
+
CodeRifts GitHub App **cannot** query branch protection (permissions are
|
|
451
|
+
contents / pull requests / checks — not `administration:read`).
|
|
452
|
+
|
|
453
|
+
`--json` is the quotable evidence document (`spec`:
|
|
454
|
+
`provider-enforcement-evidence.v1`): each layer's status, the API endpoint
|
|
455
|
+
consulted, `queried_at`. Exit **0** when a report was produced (evidence, not
|
|
456
|
+
a gate). GitLab/Bitbucket: no adapter — `UNVERIFIABLE`, never stubbed.
|
|
457
|
+
|
|
392
458
|
### Agent host files (`coderifts agent-setup`)
|
|
393
459
|
|
|
394
460
|
Writes the six CodeRifts agent-host rule files **plus** the Claude Code
|
package/bin/coderifts.js
CHANGED
|
@@ -92,7 +92,7 @@ program
|
|
|
92
92
|
.command('init [template]')
|
|
93
93
|
.description('Generate a .coderifts.yml from a policy template, or wire governed agent work (--agents)')
|
|
94
94
|
.option('--agents', 'Wire this repo for governed agent work (MCP config, rule files, host hook, CI gate)')
|
|
95
|
-
.option('--hosts <list>', 'With --agents: claude, cursor, or all (default: all)', 'all')
|
|
95
|
+
.option('--hosts <list>', 'With --agents: claude, cursor, copilot, or all (default: all)', 'all')
|
|
96
96
|
.option('--no-hook', 'With --agents: skip host hook install')
|
|
97
97
|
.option('--no-workflow', 'With --agents: skip writing .github/workflows/coderifts.yml')
|
|
98
98
|
.option('--dry-run', 'With --agents: print the plan without writing')
|
|
@@ -184,9 +184,13 @@ program
|
|
|
184
184
|
// No new GitHub writes with the CodeRifts API key (user's gh for merge; local fs for hook).
|
|
185
185
|
program
|
|
186
186
|
.command('enforce [repo]')
|
|
187
|
-
.description('Close enforcement gaps
|
|
187
|
+
.description('Close enforcement gaps (dry-run default), or --check to query provider-native pipeline protection evidence')
|
|
188
188
|
.option('--repo <owner/repo>', 'Repository (owner/repo); also accepted as a positional argument')
|
|
189
189
|
.option('--apply', 'Actually run underlying setup commands (default: dry-run only)')
|
|
190
|
+
.option('--check', 'Query GitHub + local workflows; report VERIFIED / NOT_VERIFIED / UNVERIFIABLE (read-only)')
|
|
191
|
+
.option('--env <name>', 'With --check: GitHub Environment name to query for protection rules')
|
|
192
|
+
.option('--branch <name>', 'With --check: branch to query (default: repository default branch)')
|
|
193
|
+
.option('--provider <name>', 'With --check: provider adapter (github only; others UNVERIFIABLE, never stubbed)', 'github')
|
|
190
194
|
.option('--json', 'Machine-readable JSON result')
|
|
191
195
|
.action(async (repoPositional, options) => {
|
|
192
196
|
const { runEnforce } = require('../src/commands/enforce');
|
|
@@ -194,6 +198,7 @@ program
|
|
|
194
198
|
...options,
|
|
195
199
|
repo: options.repo || repoPositional || null,
|
|
196
200
|
apply: !!options.apply,
|
|
201
|
+
check: !!options.check,
|
|
197
202
|
});
|
|
198
203
|
if (result && typeof result.exitCode === 'number') {
|
|
199
204
|
process.exitCode = result.exitCode;
|