coderifts 4.1.1 → 4.2.1

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.2.1
4
+
5
+ ### Added
6
+
7
+ - **`claude-hook` exit-0 proof block (S4).** On a governed write that is
8
+ ALLOW / CONTINUE_WITH_MONITORING (sink wired), stderr prints a compact
9
+ 3–5 line AUTHORIZED block: `decision` + `execution_action` + `decision_id`
10
+ + receipt fingerprint prefix + the boundary sentence
11
+ `authorized; execution/commit not proven by this hook`. Reuses the
12
+ `renderFinalAnswerProof` wording class. **Never stdout.** Non-governed
13
+ paths (docs-only skip, identical content) stay silent. JSONL
14
+ `hook_continue` gains additive `proof: { decision_id, fp_prefix }`.
15
+ Exit codes unchanged.
16
+
3
17
  ## 4.1.1
4
18
 
5
19
  ### Fixed
package/README.md CHANGED
@@ -54,11 +54,12 @@ A `coderifts-report.json` file is always saved to the current directory.
54
54
 
55
55
  Interactive configuration generator. Creates a `.coderifts.yml` file with industry-specific presets:
56
56
 
57
- - Default (recommended)
58
- - Fintech / Payments
59
- - Healthcare / HIPAA
60
- - Platform / API-First
61
- - E-commerce
57
+ - `startup-lean`
58
+ - `growth-balanced`
59
+ - `fintech-strict`
60
+ - `public-api-safe`
61
+ - `microservices-internal`
62
+ - `ai-agent-platform`
62
63
 
63
64
  ### `coderifts login`
64
65
 
@@ -189,6 +190,13 @@ After upgrading the `coderifts` CLI, re-run `coderifts hook install` so the
189
190
  installed hook matches the package (already-installed hooks are not
190
191
  auto-updated).
191
192
 
193
+ 2-minute Claude Code path: `coderifts hook install --claude` writes a
194
+ PreToolUse hook (`matcher: Write|Edit|MultiEdit` → `coderifts claude-hook`)
195
+ into `.claude/settings.json` (JSON-merge, backup first, idempotent).
196
+ `--global` writes `~/.claude/settings.json`. `--log <path>` embeds
197
+ `CODERIFTS_GUARD_EVENT_LOG` and `CODERIFTS_SESSION_ID` in the command.
198
+ Unparseable settings JSON → refuse, no write.
199
+
192
200
  ### Claude Code PreToolUse (`coderifts claude-hook`) — ID824
193
201
 
194
202
  Tool-call-time gate for **Claude Code**: blocks contract-touching `Write` /
@@ -198,13 +206,13 @@ Tool-call-time gate for **Claude Code**: blocks contract-touching `Write` /
198
206
 
199
207
  | Exit | Meaning |
200
208
  |------|---------|
201
- | **2** | **BLOCK** — tool call cancelled; stderr is shown to the model |
202
- | **0** | Allow, or soft-skip (no key / wrong file / parse gap / API down) |
209
+ | **2** | **BLOCK** — tool call cancelled; stderr is shown to the model. Default fail-closed: no key, API down, unreadable spec, parse-gap, missing `file_path` |
210
+ | **0** | Allow (`CONTINUE`), or skip (non-spec path / identical content). `CODERIFTS_ADVISORY=1` restores soft-allow on could-not-run sites |
203
211
  | **1** | **Never used for deny** — Claude treats exit 1 as non-blocking (action proceeds) |
204
212
 
205
213
  Push-time equivalent (git exit **1** on BLOCK): `coderifts hook install`.
206
214
 
207
- **Install path:** `npm i -g coderifts` then set key + spec (same as the git hook):
215
+ **Install path:** `coderifts hook install --claude` (or `agent-setup` writes project `.claude/settings.json` when absent). Then set key + spec:
208
216
 
209
217
  ```bash
210
218
  git config coderifts.apiKey 'cr_live_…' # or: coderifts login / CODERIFTS_API_KEY
package/bin/coderifts.js CHANGED
@@ -283,9 +283,16 @@ const hookCmd = program
283
283
  hookCmd
284
284
  .command('install')
285
285
  .description('Install the CodeRifts pre-push hook in the current Git repo')
286
- .action(() => {
286
+ .option('--claude', 'Write Claude Code PreToolUse hook to .claude/settings.json (JSON-merge)')
287
+ .option('--global', 'With --claude: write ~/.claude/settings.json instead of the project file')
288
+ .option('--log <path>', 'With --claude: embed CODERIFTS_GUARD_EVENT_LOG and CODERIFTS_SESSION_ID in the command')
289
+ .action((options) => {
287
290
  const { install } = require('../src/commands/hook');
288
- install();
291
+ install({
292
+ claude: !!options.claude,
293
+ global: !!options.global,
294
+ log: options.log,
295
+ });
289
296
  });
290
297
 
291
298
  hookCmd
package/dist/cli.js CHANGED
@@ -3007,7 +3007,7 @@ var require_package = __commonJS({
3007
3007
  "package.json"(exports2, module2) {
3008
3008
  module2.exports = {
3009
3009
  name: "coderifts",
3010
- version: "4.1.1",
3010
+ version: "4.2.1",
3011
3011
  description: "Detect breaking API changes from the command line. Works locally or with the CodeRifts cloud API.",
3012
3012
  author: "CodeRifts <hello@coderifts.com>",
3013
3013
  license: "MIT",
@@ -72976,6 +72976,10 @@ var require_init = __commonJS({
72976
72976
  yaml: `# CodeRifts Policy: Startup Lean
72977
72977
  # For fast-moving teams that want safety without friction.
72978
72978
  # Catches critical breaking changes but stays out of your way.
72979
+ #
72980
+ # Decision Spec 2.0 (comment only \u2014 this file does not set agent protocol):
72981
+ # branch on execution_action (CONTINUE | CONTINUE_WITH_MONITORING | REQUEST_APPROVAL | STOP).
72982
+ # Unknown execution_action \u2192 STOP. Analyze is not permission; authorize is required to act.
72979
72983
 
72980
72984
  failOnBreaking: true
72981
72985
 
@@ -73350,7 +73354,9 @@ generator_detection: true
73350
73354
  chalk.dim(" For agent tool-call guarding: @coderifts/agent-guard requireExecutionStateMatch"),
73351
73355
  chalk.dim(" defaults ON (absent\u2192true) \u2014 observed drift STOPS. Opt-down: 'warn' (emit, proceed)"),
73352
73356
  chalk.dim(" or false (proceed-on-drift) \u2014 see: coderifts agent-setup"),
73353
- chalk.dim(" Agent-using repo? Run: coderifts agent-setup")
73357
+ chalk.dim(" Agent-using repo? Run: coderifts agent-setup"),
73358
+ chalk.dim(" Decision Spec 2.0: branch on execution_action (CONTINUE | CONTINUE_WITH_MONITORING |"),
73359
+ chalk.dim(" REQUEST_APPROVAL | STOP). Unknown execution_action \u2192 STOP. Analyze is not permission.")
73354
73360
  ]);
73355
73361
  module2.exports = {
73356
73362
  init,
@@ -99438,6 +99444,7 @@ var require_hook = __commonJS({
99438
99444
  "use strict";
99439
99445
  var fs = require("fs");
99440
99446
  var path = require("path");
99447
+ var os = require("os");
99441
99448
  var { execSync } = require("child_process");
99442
99449
  var HOOK_MARKER = "# CodeRifts pre-push hook";
99443
99450
  var PRE_PUSH_SCRIPT = `#!/bin/sh
@@ -99698,12 +99705,111 @@ exit 0
99698
99705
  const content = fs.readFileSync(hookPath, "utf-8");
99699
99706
  return content.includes(HOOK_MARKER);
99700
99707
  }
99701
- function install() {
99702
- const gitDir = findGitDir();
99708
+ var CLAUDE_MATCHER = "Write|Edit|MultiEdit";
99709
+ var CLAUDE_HOOK_BIN = "coderifts claude-hook";
99710
+ function claudeSettingsPath({ global: isGlobal, cwd } = {}) {
99711
+ if (isGlobal) return path.join(os.homedir(), ".claude", "settings.json");
99712
+ return path.join(cwd || process.cwd(), ".claude", "settings.json");
99713
+ }
99714
+ function claudeHookCommand(logPath) {
99715
+ if (!logPath) return CLAUDE_HOOK_BIN;
99716
+ const abs = path.resolve(String(logPath));
99717
+ return `CODERIFTS_GUARD_EVENT_LOG=${abs} CODERIFTS_SESSION_ID=coderifts-claude-hook ${CLAUDE_HOOK_BIN}`;
99718
+ }
99719
+ function isOurPreToolUseEntry(entry, command) {
99720
+ if (!entry || typeof entry !== "object") return false;
99721
+ if (entry.matcher !== CLAUDE_MATCHER) return false;
99722
+ const hooks = Array.isArray(entry.hooks) ? entry.hooks : [];
99723
+ return hooks.some((h) => h && h.type === "command" && String(h.command || "") === command);
99724
+ }
99725
+ function installClaudeHook(opts = {}) {
99726
+ const cwd = opts.cwd || process.cwd();
99727
+ const home = opts.homeDir || os.homedir();
99728
+ const dest = opts.global ? path.join(home, ".claude", "settings.json") : path.join(cwd, ".claude", "settings.json");
99729
+ const command = claudeHookCommand(opts.logPath);
99730
+ const block = {
99731
+ matcher: CLAUDE_MATCHER,
99732
+ hooks: [{ type: "command", command, timeout: 60 }]
99733
+ };
99734
+ let existing = {};
99735
+ let hadFile = false;
99736
+ if (fs.existsSync(dest)) {
99737
+ hadFile = true;
99738
+ let raw;
99739
+ try {
99740
+ raw = fs.readFileSync(dest, "utf8");
99741
+ } catch (err) {
99742
+ const message = `Error: cannot read ${dest} (${err && err.message}) \u2014 refusing to write.`;
99743
+ console.error(message);
99744
+ process.exitCode = 1;
99745
+ return { exitCode: 1, code: "READ_FAILED", path: dest, message };
99746
+ }
99747
+ if (String(raw).trim() !== "") {
99748
+ try {
99749
+ existing = JSON.parse(raw);
99750
+ } catch (err) {
99751
+ const message = `Error: ${dest} is not valid JSON \u2014 refusing (no write). Fix or remove the file, then re-run.`;
99752
+ console.error(message);
99753
+ process.exitCode = 1;
99754
+ return { exitCode: 1, code: "PARSE_FAILED", path: dest, message };
99755
+ }
99756
+ if (!existing || typeof existing !== "object" || Array.isArray(existing)) {
99757
+ const message = `Error: ${dest} JSON root is not an object \u2014 refusing (no write).`;
99758
+ console.error(message);
99759
+ process.exitCode = 1;
99760
+ return { exitCode: 1, code: "PARSE_FAILED", path: dest, message };
99761
+ }
99762
+ }
99763
+ }
99764
+ const hooksRoot = existing.hooks && typeof existing.hooks === "object" && !Array.isArray(existing.hooks) ? { ...existing.hooks } : {};
99765
+ const pre = Array.isArray(hooksRoot.PreToolUse) ? hooksRoot.PreToolUse.slice() : [];
99766
+ if (pre.some((e) => isOurPreToolUseEntry(e, command))) {
99767
+ console.log(`Claude Code hook already installed at ${dest} (no-op).`);
99768
+ return { exitCode: 0, code: "NOOP", path: dest, wrote: false };
99769
+ }
99770
+ const nextPre = pre.concat([block]);
99771
+ const next = {
99772
+ ...existing,
99773
+ hooks: { ...hooksRoot, PreToolUse: nextPre }
99774
+ };
99775
+ const serialized = `${JSON.stringify(next, null, 2)}
99776
+ `;
99777
+ let backedUp;
99778
+ if (hadFile) {
99779
+ backedUp = `${dest}.bak`;
99780
+ fs.copyFileSync(dest, backedUp);
99781
+ }
99782
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
99783
+ fs.writeFileSync(dest, serialized, "utf8");
99784
+ console.log(`Claude Code PreToolUse hook written to ${dest}`);
99785
+ if (backedUp) console.log(`Backup: ${backedUp}`);
99786
+ console.log("matcher Write|Edit|MultiEdit \u2192 coderifts claude-hook (exit 2 = BLOCK).");
99787
+ return { exitCode: 0, code: "OK", path: dest, backedUp, wrote: true };
99788
+ }
99789
+ function install(options = {}) {
99790
+ if (options.global && !options.claude) {
99791
+ console.error("Error: --global requires --claude (writes ~/.claude/settings.json).");
99792
+ process.exitCode = 1;
99793
+ return { exitCode: 1, code: "USAGE" };
99794
+ }
99795
+ if (options.claude) {
99796
+ const r = installClaudeHook({
99797
+ global: !!options.global,
99798
+ logPath: options.log,
99799
+ cwd: options.cwd,
99800
+ homeDir: options.homeDir
99801
+ });
99802
+ if (r.exitCode !== 0) return r;
99803
+ }
99804
+ const gitDir = findGitDir(options.cwd);
99703
99805
  if (!gitDir) {
99806
+ if (options.claude) {
99807
+ console.log("Not inside a Git repository \u2014 skipped pre-push hook.");
99808
+ return { exitCode: 0, code: "OK" };
99809
+ }
99704
99810
  console.error("Error: Not inside a Git repository.");
99705
99811
  process.exitCode = 1;
99706
- return;
99812
+ return { exitCode: 1, code: "NO_GIT" };
99707
99813
  }
99708
99814
  const hooksDir = path.join(gitDir, "hooks");
99709
99815
  if (!fs.existsSync(hooksDir)) {
@@ -99782,7 +99888,19 @@ exit 0
99782
99888
  }
99783
99889
  }
99784
99890
  }
99785
- module2.exports = { install, uninstall, status, PRE_PUSH_SCRIPT, HOOK_MARKER, findGitDir, isCodeRiftsHook };
99891
+ module2.exports = {
99892
+ install,
99893
+ uninstall,
99894
+ status,
99895
+ PRE_PUSH_SCRIPT,
99896
+ HOOK_MARKER,
99897
+ findGitDir,
99898
+ isCodeRiftsHook,
99899
+ installClaudeHook,
99900
+ claudeSettingsPath,
99901
+ claudeHookCommand,
99902
+ CLAUDE_MATCHER
99903
+ };
99786
99904
  }
99787
99905
  });
99788
99906
 
@@ -100063,12 +100181,12 @@ var require_agent_host_files_embedded = __commonJS({
100063
100181
  ".claude/settings.json"
100064
100182
  ]);
100065
100183
  var AGENT_HOST_FILES = Object.freeze({
100066
- "AGENTS.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts agent rules\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n',
100067
- "CLAUDE.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n',
100068
- ".cursor/rules/coderifts.mdc": '---\ndescription: CodeRifts API governance \u2014 when to preflight and how to branch\nglobs:\nalwaysApply: true\n---\n\n<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n',
100069
- ".github/copilot-instructions.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts instructions for GitHub Copilot\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n',
100070
- "coderifts-langgraph-policy.js": '// GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js\n// System policy string for a LangGraph (or similar) agent. Content is generated;\n// identical rule sentences to AGENTS.md / other formats.\n\'use strict\';\n\nmodule.exports = "Call `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\\n\\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\\n\\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\\n\\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\\n\\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not \\"proceed with caution\\" without monitoring.\\n\\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\\n\\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\\n\\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\\n\\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\\n\\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\\n\\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.";\n',
100071
- "openai-agent-instructions.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts agent instructions\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n',
100184
+ "AGENTS.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts agent rules\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational (`may_execute` is always false) and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n',
100185
+ "CLAUDE.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational (`may_execute` is always false) and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n',
100186
+ ".cursor/rules/coderifts.mdc": '---\ndescription: CodeRifts API governance \u2014 when to preflight and how to branch\nglobs:\nalwaysApply: true\n---\n\n<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational (`may_execute` is always false) and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n',
100187
+ ".github/copilot-instructions.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts instructions for GitHub Copilot\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational (`may_execute` is always false) and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n',
100188
+ "coderifts-langgraph-policy.js": '// GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js\n// System policy string for a LangGraph (or similar) agent. Content is generated;\n// identical rule sentences to AGENTS.md / other formats.\n\'use strict\';\n\nmodule.exports = "Call `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\\n\\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\\n\\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\\n\\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\\n\\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not \\"proceed with caution\\" without monitoring.\\n\\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\\n\\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\\n\\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\\n\\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\\n\\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\\n\\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\\n\\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational (`may_execute` is always false) and is not permission. Read `execution_action` on the `decision_result` envelope.\\n\\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\\n\\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\\n\\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.";\n',
100189
+ "openai-agent-instructions.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts agent instructions\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call CodeRifts tools for a documentation-only change (README, guides, comments) with no contract artifact content change.\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nA receipt is operation-scoped: a merge receipt never authorizes a deploy or publish. When the operation changes, you MUST call `preflight_change_set` again with the new `context.operation` \u2014 do not decline, re-preflight.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational (`may_execute` is always false) and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n',
100072
100190
  ".claude/settings.json": '{\n "hooks": {\n "PreToolUse": [\n {\n "matcher": "Write|Edit|MultiEdit",\n "hooks": [\n {\n "type": "command",\n "command": "coderifts claude-hook",\n "timeout": 60\n }\n ]\n }\n ]\n }\n}\n'
100073
100191
  });
100074
100192
  module2.exports = { AGENT_HOST_FILES, AGENT_HOST_PATHS };
@@ -101283,6 +101401,27 @@ var require_claude_hook = __commonJS({
101283
101401
  const fp = dr.fingerprint || d.fingerprint || d.verdict_fingerprint || d.input_fingerprint;
101284
101402
  return typeof fp === "string" && fp.length > 0 ? fp : void 0;
101285
101403
  }
101404
+ function fingerprintPrefix(fp) {
101405
+ if (typeof fp !== "string" || fp.length === 0) return void 0;
101406
+ const colon = fp.indexOf(":");
101407
+ if (colon > 0 && colon < fp.length - 1) {
101408
+ const scheme = fp.slice(0, colon + 1);
101409
+ const rest = fp.slice(colon + 1);
101410
+ return scheme + rest.slice(0, 12) + (rest.length > 12 ? "\u2026" : "");
101411
+ }
101412
+ return fp.length > 16 ? `${fp.slice(0, 16)}\u2026` : fp;
101413
+ }
101414
+ function renderAllowProofBlock({ decision, executionAction, decisionId, fingerprint } = {}) {
101415
+ const decPart = decision ? ` decision=${decision}` : "";
101416
+ const eaPart = executionAction ? ` execution_action=${executionAction}` : "";
101417
+ const idPart = decisionId ? ` decision_id=${decisionId}` : "";
101418
+ const lines = [`CodeRifts claude-hook: AUTHORIZED${decPart}${eaPart}${idPart}`];
101419
+ const pref = fingerprintPrefix(fingerprint);
101420
+ if (pref) lines.push(`- receipt: ${pref}`);
101421
+ lines.push("- Interpretation: authorized at verify time for the bound scope only \u2014 see Limits.");
101422
+ lines.push("- authorized; execution/commit not proven by this hook");
101423
+ return lines.join("\n");
101424
+ }
101286
101425
  function hookSessionId(env) {
101287
101426
  const fromEnv = env && env.CODERIFTS_SESSION_ID && String(env.CODERIFTS_SESSION_ID).trim();
101288
101427
  if (fromEnv) return fromEnv;
@@ -101578,7 +101717,17 @@ var require_claude_hook = __commonJS({
101578
101717
  } else if (r.exitCode === 0 && r.site && advisory && !strict) {
101579
101718
  logEv({ type: "hook_advisory_passthrough", exit: 0, decision: r.decision || null, ...extra, cause: r.site });
101580
101719
  } else {
101581
- logEv({ type: "hook_continue", exit: 0, ...extra, cause: r.reason });
101720
+ const proof = r.reason === "allow" ? {
101721
+ decision_id: r.decisionId != null ? r.decisionId : extra.decisionId || null,
101722
+ fp_prefix: fingerprintPrefix(r.fingerprint) || null
101723
+ } : void 0;
101724
+ logEv({
101725
+ type: "hook_continue",
101726
+ exit: 0,
101727
+ ...extra,
101728
+ cause: r.reason,
101729
+ ...proof ? { proof } : {}
101730
+ });
101582
101731
  }
101583
101732
  return r;
101584
101733
  };
@@ -101748,20 +101897,34 @@ var require_claude_hook = __commonJS({
101748
101897
  decisionId: mapped.decisionId
101749
101898
  });
101750
101899
  }
101900
+ errLog(renderAllowProofBlock({
101901
+ decision: mapped.decision,
101902
+ executionAction: mapped.executionAction,
101903
+ decisionId: mapped.decisionId,
101904
+ fingerprint
101905
+ }));
101751
101906
  return emitTerminal({
101752
101907
  exitCode: 0,
101753
101908
  reason: "allow",
101754
101909
  severity: mapped.severity === "WARN" ? "MONITOR" : mapped.severity,
101755
101910
  decision: mapped.decision,
101756
- decisionId: mapped.decisionId
101911
+ decisionId: mapped.decisionId,
101912
+ fingerprint
101757
101913
  });
101758
101914
  }
101915
+ errLog(renderAllowProofBlock({
101916
+ decision: mapped.decision,
101917
+ executionAction: mapped.executionAction,
101918
+ decisionId: mapped.decisionId,
101919
+ fingerprint
101920
+ }));
101759
101921
  return emitTerminal({
101760
101922
  exitCode: 0,
101761
101923
  reason: "allow",
101762
101924
  severity: "ALLOW",
101763
101925
  decision: mapped.decision,
101764
- decisionId: mapped.decisionId
101926
+ decisionId: mapped.decisionId,
101927
+ fingerprint
101765
101928
  });
101766
101929
  }
101767
101930
  module2.exports = {
@@ -101785,6 +101948,8 @@ var require_claude_hook = __commonJS({
101785
101948
  USAGE,
101786
101949
  appendGuardEventLog,
101787
101950
  extractFingerprint,
101951
+ fingerprintPrefix,
101952
+ renderAllowProofBlock,
101788
101953
  HOOK_TRIGGER_SOURCE
101789
101954
  };
101790
101955
  }
@@ -103799,9 +103964,13 @@ ${USAGE}
103799
103964
  }
103800
103965
  });
103801
103966
  var hookCmd = program.command("hook").description("Manage the CodeRifts pre-push Git hook");
103802
- hookCmd.command("install").description("Install the CodeRifts pre-push hook in the current Git repo").action(() => {
103967
+ hookCmd.command("install").description("Install the CodeRifts pre-push hook in the current Git repo").option("--claude", "Write Claude Code PreToolUse hook to .claude/settings.json (JSON-merge)").option("--global", "With --claude: write ~/.claude/settings.json instead of the project file").option("--log <path>", "With --claude: embed CODERIFTS_GUARD_EVENT_LOG and CODERIFTS_SESSION_ID in the command").action((options) => {
103803
103968
  const { install } = require_hook();
103804
- install();
103969
+ install({
103970
+ claude: !!options.claude,
103971
+ global: !!options.global,
103972
+ log: options.log
103973
+ });
103805
103974
  });
103806
103975
  hookCmd.command("uninstall").description("Remove the CodeRifts pre-push hook from the current Git repo").action(() => {
103807
103976
  const { uninstall } = require_hook();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coderifts",
3
- "version": "4.1.1",
3
+ "version": "4.2.1",
4
4
  "description": "Detect breaking API changes from the command line. Works locally or with the CodeRifts cloud API.",
5
5
  "author": "CodeRifts <hello@coderifts.com>",
6
6
  "license": "MIT",