coderifts 3.3.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +17 -10
- package/bin/coderifts.js +3 -2
- package/dist/cli.js +266 -108
- package/package.json +3 -2
- package/scripts/assert-guard-major.js +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 4.0.0
|
|
4
|
+
|
|
5
|
+
**Breaking** — `coderifts claude-hook` is fail-closed by default. The CLI now
|
|
6
|
+
depends on `@coderifts/agent-guard` ^8.1.1.
|
|
7
|
+
|
|
8
|
+
### Breaking
|
|
9
|
+
- **`claude-hook` default is fail-closed (P0-3/P0-4).** No API key, API
|
|
10
|
+
unreachable, disk unreadable, or edit-apply failure on the spec path →
|
|
11
|
+
**exit 2** (`enforce_indeterminate`), not exit 0. `REQUEST_APPROVAL` →
|
|
12
|
+
exit 2 (`approval_required`). `CONTINUE_WITH_MONITORING` without a
|
|
13
|
+
host-asserted monitoring sink → exit 2. Empty verdict is no longer
|
|
14
|
+
mapped to ALLOW (P0 #5).
|
|
15
|
+
- **Migration:** hosts that ran the hook without a key / without
|
|
16
|
+
`CODERIFTS_STRICT` will now **block** tool calls. Explicit opt-out:
|
|
17
|
+
`CODERIFTS_ADVISORY=1` restores the old soft-allow on "governance could
|
|
18
|
+
not run" sites. `CODERIFTS_STRICT=1` remains fail-closed and cannot be
|
|
19
|
+
weakened by ADVISORY.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- **`@coderifts/agent-guard` `^6.4.0` → `^8.1.1`.** CLI still calls only
|
|
23
|
+
`deployGate` / `matchGlob` (not the wrap/TOCTOU path). `inescapable_deploy`
|
|
24
|
+
on 8.x is `ENFORCING ∧ ¬bypass ∧ expected_fingerprint` rebound.
|
|
25
|
+
- **`deployReportResiduals`:** rebound-missing is `change_set_not_rebound`,
|
|
26
|
+
never `bypass_open`. Enforcement-axis residuals still named first (same
|
|
27
|
+
order as guard `residuals[]`). CLI AND on the inescapable flag is kept
|
|
28
|
+
(never widen).
|
|
29
|
+
- **`MIN_GUARD_MAJOR`:** 6 → 8 (`scripts/assert-guard-major.js`).
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
- **Installer copy (P0 #9 / e76e846):** `agent-setup` / `init` teach
|
|
33
|
+
guard@8 execution-state **DEFAULT ON**, not the old OFF.
|
|
34
|
+
|
|
35
|
+
## 3.4.0
|
|
36
|
+
|
|
37
|
+
### Agent-setup
|
|
38
|
+
|
|
39
|
+
- Rule files now state that receipts are operation-scoped (a merge receipt never authorizes deploy/publish; re-preflight with the new `context.operation` — do not decline) and that a stale receipt on a changed head needs a new preflight (`verify_receipt` cannot re-diff).
|
|
40
|
+
- Hosts with existing agent-setup files: `coderifts agent-setup --force` to pick up the new paragraphs; `--check` will report drift until then.
|
package/README.md
CHANGED
|
@@ -236,17 +236,22 @@ git config coderifts.specPath api/openapi.yaml # default if omitted
|
|
|
236
236
|
- **User** `~/.claude/settings.json` — personal; applies to all projects on this machine.
|
|
237
237
|
- Matcher is case-sensitive tool names/regex. Exit-2 blocking is **Claude Code** semantics; the same decision discipline at push-time is the git pre-push hook above.
|
|
238
238
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
239
|
+
**Fail-closed default:** missing API key, API unreachable, disk unreadable, or
|
|
240
|
+
edit-apply failure on the spec path is **exit 2** (`enforce_indeterminate`) —
|
|
241
|
+
absence of a key is not ALLOW. `REQUEST_APPROVAL` is **exit 2**
|
|
242
|
+
(`approval_required`). `CONTINUE_WITH_MONITORING` is **exit 2**
|
|
243
|
+
(`monitoring_unwired`) unless the host asserts a sink
|
|
244
|
+
(`CODERIFTS_MONITORING_SINK_WIRED=1` or `git config coderifts.monitoringSinkWired true`)
|
|
245
|
+
— a host claim, not delivery proof.
|
|
246
|
+
|
|
247
|
+
**`CODERIFTS_ADVISORY=1|true`:** explicit opt-out that restores soft-allow on
|
|
248
|
+
“governance could not run” sites. Not implied by a missing key.
|
|
249
|
+
|
|
250
|
+
**`CODERIFTS_STRICT=1|true`:** same fail-closed as the default; cannot be
|
|
251
|
+
weakened by `CODERIFTS_ADVISORY`.
|
|
247
252
|
|
|
248
253
|
```bash
|
|
249
|
-
|
|
254
|
+
CODERIFTS_ADVISORY=1 coderifts claude-hook
|
|
250
255
|
```
|
|
251
256
|
|
|
252
257
|
### `coderifts status [repo]`
|
|
@@ -485,7 +490,9 @@ Two honest modes:
|
|
|
485
490
|
|----------|-------------|
|
|
486
491
|
| `CODERIFTS_API_KEY` | API key (alternative to `coderifts login`) |
|
|
487
492
|
| `CODERIFTS_OASDIFF_BIN` | Explicit path to the `oasdiff` binary (overrides auto-detect) |
|
|
488
|
-
| `CODERIFTS_STRICT` | `claude-hook
|
|
493
|
+
| `CODERIFTS_STRICT` | `claude-hook`: `1` or `true` pins fail-closed (cannot be weakened by `CODERIFTS_ADVISORY`). Default is already fail-closed. |
|
|
494
|
+
| `CODERIFTS_ADVISORY` | `claude-hook`: `1` or `true` is the **explicit** soft-allow opt-out on “governance could not run” sites. Absence of a key is not this flag. |
|
|
495
|
+
| `CODERIFTS_MONITORING_SINK_WIRED` | `claude-hook`: `1` or `true` host-asserts a monitoring sink so `CONTINUE_WITH_MONITORING` may exit 0. Not delivery proof. |
|
|
489
496
|
| `CODERIFTS_DEPLOY_ENFORCE` | `deploy-gate`: `true` marks the step enforcing (same as `--enforce`); `unknown` is explicitly unobservable (never assume ENFORCING) |
|
|
490
497
|
| `NO_COLOR` | Disable colored output |
|
|
491
498
|
|
package/bin/coderifts.js
CHANGED
|
@@ -259,8 +259,9 @@ program
|
|
|
259
259
|
program
|
|
260
260
|
.command('claude-hook')
|
|
261
261
|
.description(
|
|
262
|
-
'Claude Code PreToolUse gate: block contract-touching Write|Edit|MultiEdit on BLOCK/STOP
|
|
263
|
-
+ '(exit 2).
|
|
262
|
+
'Claude Code PreToolUse gate: block contract-touching Write|Edit|MultiEdit on BLOCK/STOP/'
|
|
263
|
+
+ 'REQUEST_APPROVAL (exit 2). Fail-closed when governance cannot run; '
|
|
264
|
+
+ 'CODERIFTS_ADVISORY=1 is the explicit soft opt-out.',
|
|
264
265
|
)
|
|
265
266
|
.addHelpText('after', () => {
|
|
266
267
|
const { USAGE } = require('../src/commands/claude-hook');
|
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: "
|
|
3010
|
+
version: "4.0.0",
|
|
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",
|
|
@@ -3020,6 +3020,7 @@ var require_package = __commonJS({
|
|
|
3020
3020
|
"bin/",
|
|
3021
3021
|
"scripts/",
|
|
3022
3022
|
"README.md",
|
|
3023
|
+
"CHANGELOG.md",
|
|
3023
3024
|
"corpus/"
|
|
3024
3025
|
],
|
|
3025
3026
|
keywords: [
|
|
@@ -3051,7 +3052,7 @@ var require_package = __commonJS({
|
|
|
3051
3052
|
test: "node --test test/*.test.js"
|
|
3052
3053
|
},
|
|
3053
3054
|
dependencies: {
|
|
3054
|
-
"@coderifts/agent-guard": "^
|
|
3055
|
+
"@coderifts/agent-guard": "^8.1.1",
|
|
3055
3056
|
chalk: "^4.1.2",
|
|
3056
3057
|
"cli-table3": "^0.6.4",
|
|
3057
3058
|
commander: "^12.0.0",
|
|
@@ -67465,43 +67466,53 @@ var require_guard = __commonJS({
|
|
|
67465
67466
|
}
|
|
67466
67467
|
const enforceable = receiptVerified && (kind === "ALLOW" || sinkWired);
|
|
67467
67468
|
if (enforceable) {
|
|
67468
|
-
const execStateMode = config.requireExecutionStateMatch;
|
|
67469
|
-
if (execStateMode ===
|
|
67470
|
-
|
|
67471
|
-
|
|
67472
|
-
|
|
67473
|
-
|
|
67474
|
-
|
|
67475
|
-
environment: config.environment
|
|
67476
|
-
},
|
|
67477
|
-
envelope
|
|
67469
|
+
const execStateMode = config.requireExecutionStateMatch === void 0 ? true : config.requireExecutionStateMatch;
|
|
67470
|
+
if (execStateMode === false) {
|
|
67471
|
+
emit(config, {
|
|
67472
|
+
type: "execution_state_check_disabled",
|
|
67473
|
+
at: iso(),
|
|
67474
|
+
decisionId: envelope.decision_id,
|
|
67475
|
+
cause: "requireExecutionStateMatch_false"
|
|
67478
67476
|
});
|
|
67479
|
-
|
|
67480
|
-
|
|
67481
|
-
|
|
67482
|
-
|
|
67483
|
-
|
|
67484
|
-
|
|
67485
|
-
|
|
67486
|
-
|
|
67487
|
-
|
|
67488
|
-
|
|
67489
|
-
|
|
67490
|
-
|
|
67491
|
-
|
|
67492
|
-
|
|
67493
|
-
|
|
67494
|
-
|
|
67495
|
-
|
|
67496
|
-
|
|
67497
|
-
|
|
67498
|
-
|
|
67499
|
-
|
|
67500
|
-
|
|
67501
|
-
|
|
67502
|
-
|
|
67503
|
-
|
|
67477
|
+
const offVerdict = kind === "ALLOW" ? { kind: "ALLOW", action: "CONTINUE", envelope, receiptVerified } : { kind: "MONITOR", action: "CONTINUE_WITH_MONITORING", envelope, receiptVerified };
|
|
67478
|
+
return runUnenforced(config, executeFactory, envelope, offVerdict, true, redacted, freshBasis, cwBasis);
|
|
67479
|
+
}
|
|
67480
|
+
const et = (0, execution_time_fingerprint_js_1.checkExecutionTimeFingerprint)({
|
|
67481
|
+
artifacts: detection.artifacts,
|
|
67482
|
+
context: {
|
|
67483
|
+
operation: config.operation ?? "tool_call",
|
|
67484
|
+
environment: config.environment
|
|
67485
|
+
},
|
|
67486
|
+
envelope
|
|
67487
|
+
});
|
|
67488
|
+
if (!et.match) {
|
|
67489
|
+
const unmeasurable = (0, execution_time_fingerprint_js_1.isUnmeasurableExecutionStateReason)(et.reason);
|
|
67490
|
+
if (execStateMode === true) {
|
|
67491
|
+
breakerRecord(config);
|
|
67492
|
+
return closedIntegrity(config, unmeasurable ? "EXECUTION_STATE_UNMEASURABLE" : "EXECUTION_STATE_DRIFT", failPolicy, fctx, cwctx, redacted, detection.artifacts);
|
|
67493
|
+
}
|
|
67494
|
+
if (unmeasurable) {
|
|
67495
|
+
emit(config, {
|
|
67496
|
+
type: "execution_state_unmeasurable",
|
|
67497
|
+
at: iso(),
|
|
67498
|
+
decisionId: envelope.decision_id,
|
|
67499
|
+
current_fingerprint: et.current_fingerprint,
|
|
67500
|
+
authorized_fingerprint: et.authorized_fingerprint,
|
|
67501
|
+
reason: et.reason,
|
|
67502
|
+
note: execution_time_fingerprint_js_1.EXECUTION_STATE_UNMEASURABLE_NOTE
|
|
67503
|
+
});
|
|
67504
|
+
} else {
|
|
67505
|
+
emit(config, {
|
|
67506
|
+
type: "execution_state_drift_observed",
|
|
67507
|
+
at: iso(),
|
|
67508
|
+
decisionId: envelope.decision_id,
|
|
67509
|
+
current_fingerprint: et.current_fingerprint,
|
|
67510
|
+
authorized_fingerprint: et.authorized_fingerprint,
|
|
67511
|
+
reason: et.reason
|
|
67512
|
+
});
|
|
67504
67513
|
}
|
|
67514
|
+
const warnVerdict = kind === "ALLOW" ? { kind: "ALLOW", action: "CONTINUE", envelope, receiptVerified } : { kind: "MONITOR", action: "CONTINUE_WITH_MONITORING", envelope, receiptVerified };
|
|
67515
|
+
return runUnenforced(config, executeFactory, envelope, warnVerdict, true, redacted, freshBasis, cwBasis);
|
|
67505
67516
|
}
|
|
67506
67517
|
const approved = kind === "ALLOW" ? { kind: "ALLOW", action: "CONTINUE", envelope, receiptVerified: true } : { kind: "MONITOR", action: "CONTINUE_WITH_MONITORING", envelope, receiptVerified: true };
|
|
67507
67518
|
return runEnforced(config, executeFactory, approved, redacted, freshBasis, cwBasis);
|
|
@@ -69861,24 +69872,25 @@ var require_merge_gate = __commonJS({
|
|
|
69861
69872
|
if (!isAllowClass(receipt, allowWarnMerge)) {
|
|
69862
69873
|
return fail("failure", "decision_not_allow");
|
|
69863
69874
|
}
|
|
69864
|
-
const
|
|
69875
|
+
const protectionOk = enforcement_state === "ENFORCING" && protection.admin_bypass_possible === false;
|
|
69876
|
+
const appBound = protection.required_check_app_bound === true;
|
|
69877
|
+
const rebound = rc.expected_fingerprint != null && String(rc.expected_fingerprint).length > 0;
|
|
69878
|
+
const inescapable_merge = protectionOk && appBound && rebound;
|
|
69865
69879
|
const residuals = [];
|
|
69866
|
-
if (!
|
|
69880
|
+
if (!protectionOk) {
|
|
69867
69881
|
if (enforcement_state === "ENFORCING")
|
|
69868
69882
|
residuals.push("admin_bypass_open");
|
|
69869
69883
|
else if (enforcement_state === "ADVISORY")
|
|
69870
69884
|
residuals.push("protection_advisory_only");
|
|
69871
69885
|
else
|
|
69872
69886
|
residuals.push("protection_not_configured");
|
|
69887
|
+
} else if (protection.required_check_app_bound === true) {
|
|
69888
|
+
} else if (protection.required_check_app_bound === false) {
|
|
69889
|
+
residuals.push("required_check_app_not_bound");
|
|
69873
69890
|
} else {
|
|
69874
|
-
|
|
69875
|
-
} else if (protection.required_check_app_bound === false) {
|
|
69876
|
-
residuals.push("required_check_app_not_bound");
|
|
69877
|
-
} else {
|
|
69878
|
-
residuals.push("required_check_app_binding_unknown");
|
|
69879
|
-
}
|
|
69891
|
+
residuals.push("required_check_app_binding_unknown");
|
|
69880
69892
|
}
|
|
69881
|
-
if (
|
|
69893
|
+
if (!rebound) {
|
|
69882
69894
|
residuals.push("change_set_not_rebound");
|
|
69883
69895
|
}
|
|
69884
69896
|
const residual = residuals.length > 0 ? residuals[0] : void 0;
|
|
@@ -70001,15 +70013,17 @@ var require_deploy_gate = __commonJS({
|
|
|
70001
70013
|
if (!isAllowClass(receipt, allowWarnDeploy)) {
|
|
70002
70014
|
return deny("failure", "decision_not_allow");
|
|
70003
70015
|
}
|
|
70004
|
-
const
|
|
70016
|
+
const enforcementOk = enforcement_state === "ENFORCING" && enf.bypass_possible === false;
|
|
70017
|
+
const rebound = rc.expected_fingerprint != null && String(rc.expected_fingerprint).length > 0;
|
|
70018
|
+
const inescapable_deploy = enforcementOk && rebound;
|
|
70005
70019
|
const residuals = [];
|
|
70006
|
-
if (!
|
|
70020
|
+
if (!enforcementOk) {
|
|
70007
70021
|
if (enforcement_state === "ENFORCING")
|
|
70008
70022
|
residuals.push("bypass_open");
|
|
70009
70023
|
else
|
|
70010
70024
|
residuals.push("enforcement_not_configured");
|
|
70011
70025
|
}
|
|
70012
|
-
if (
|
|
70026
|
+
if (!rebound) {
|
|
70013
70027
|
residuals.push("change_set_not_rebound");
|
|
70014
70028
|
}
|
|
70015
70029
|
const residual = residuals.length > 0 ? residuals[0] : void 0;
|
|
@@ -70298,6 +70312,7 @@ var require_with_coderifts = __commonJS({
|
|
|
70298
70312
|
var COMPOSITION_CALL_POLICY_COMPLETE = false;
|
|
70299
70313
|
var RESIDUAL_CALL_POLICY_INCOMPLETE = "composition_call_policy_incomplete";
|
|
70300
70314
|
var RESIDUAL_FRESHNESS_NOT_CONFIGURED = "composition_freshness_not_configured";
|
|
70315
|
+
var RESIDUAL_CALLS_OUTSIDE_GUARDED_PATH = "calls_outside_guarded_path_invisible";
|
|
70301
70316
|
var RESIDUAL_FORCED_READONLY = "composition_forced_readonly_on_heuristic_mutator";
|
|
70302
70317
|
var RESIDUAL_UNKNOWN_READONLY = "composition_unknown_treated_as_readonly";
|
|
70303
70318
|
var COVERAGE_STRENGTH = {
|
|
@@ -70309,6 +70324,30 @@ var require_with_coderifts = __commonJS({
|
|
|
70309
70324
|
function coverageRank(coverage) {
|
|
70310
70325
|
return Object.prototype.hasOwnProperty.call(COVERAGE_STRENGTH, coverage) ? COVERAGE_STRENGTH[coverage] : void 0;
|
|
70311
70326
|
}
|
|
70327
|
+
function isEnforcingStrict(input) {
|
|
70328
|
+
return input.profile === "ENFORCING_STRICT";
|
|
70329
|
+
}
|
|
70330
|
+
function enforcingStrictWeakenFlags(input) {
|
|
70331
|
+
const flags = [];
|
|
70332
|
+
if (input.requireCoverage !== void 0) {
|
|
70333
|
+
const rank = coverageRank(input.requireCoverage);
|
|
70334
|
+
if (rank !== void 0 && rank < COVERAGE_STRENGTH.COMPLETE)
|
|
70335
|
+
flags.push("requireCoverage");
|
|
70336
|
+
}
|
|
70337
|
+
if (input.requireFreshness === false)
|
|
70338
|
+
flags.push("requireFreshness");
|
|
70339
|
+
if (input.requireExecutionStateMatch === false || input.requireExecutionStateMatch === "warn") {
|
|
70340
|
+
flags.push("requireExecutionStateMatch");
|
|
70341
|
+
}
|
|
70342
|
+
if (input.requireConditionalWrite === false)
|
|
70343
|
+
flags.push("requireConditionalWrite");
|
|
70344
|
+
const reg = input.registry ?? {};
|
|
70345
|
+
if (reg.failOnUnguardedMutator === false)
|
|
70346
|
+
flags.push("failOnUnguardedMutator");
|
|
70347
|
+
if (reg.unknownToolPolicy === "readonly")
|
|
70348
|
+
flags.push("unknownToolPolicy");
|
|
70349
|
+
return flags;
|
|
70350
|
+
}
|
|
70312
70351
|
async function safeOnSettledCall(onSettledCall, payload) {
|
|
70313
70352
|
try {
|
|
70314
70353
|
await Promise.resolve(onSettledCall(payload));
|
|
@@ -70495,6 +70534,18 @@ var require_with_coderifts = __commonJS({
|
|
|
70495
70534
|
if (input.requireCoverage !== void 0 && coverageRank(input.requireCoverage) === void 0) {
|
|
70496
70535
|
problems.push(`\`requireCoverage\` must be one of COMPLETE | PARTIAL | BYPASSED | UNKNOWN (got ${JSON.stringify(input.requireCoverage)})`);
|
|
70497
70536
|
}
|
|
70537
|
+
if (input.profile !== void 0 && input.profile !== "ENFORCING_STRICT") {
|
|
70538
|
+
problems.push(`\`profile\` must be 'ENFORCING_STRICT' when set (got ${JSON.stringify(input.profile)})`);
|
|
70539
|
+
}
|
|
70540
|
+
if (isEnforcingStrict(input)) {
|
|
70541
|
+
const weaken = enforcingStrictWeakenFlags(input);
|
|
70542
|
+
if (weaken.length > 0) {
|
|
70543
|
+
problems.push(`ENFORCING_STRICT cannot be weakened: ${weaken.join(", ")} conflicts`);
|
|
70544
|
+
}
|
|
70545
|
+
if (typeof input.resolvePriorContent !== "function") {
|
|
70546
|
+
problems.push("ENFORCING_STRICT cannot be weakened: resolvePriorContent conflicts");
|
|
70547
|
+
}
|
|
70548
|
+
}
|
|
70498
70549
|
if (problems.length > 0) {
|
|
70499
70550
|
throw new Error(`withCodeRifts: construction aborted \u2014 ${problems.length} condition(s):
|
|
70500
70551
|
` + problems.map((p) => ` - ${p}`).join("\n"));
|
|
@@ -70533,20 +70584,27 @@ var require_with_coderifts = __commonJS({
|
|
|
70533
70584
|
if (input.requireExecutionStateMatch !== void 0) {
|
|
70534
70585
|
guard.requireExecutionStateMatch = input.requireExecutionStateMatch;
|
|
70535
70586
|
}
|
|
70587
|
+
const strict = isEnforcingStrict(input);
|
|
70588
|
+
if (strict) {
|
|
70589
|
+
guard.requireFreshness = true;
|
|
70590
|
+
guard.requireConditionalWrite = true;
|
|
70591
|
+
guard.requireExecutionStateMatch = true;
|
|
70592
|
+
}
|
|
70536
70593
|
const config = {
|
|
70537
70594
|
guard,
|
|
70538
|
-
unknownToolPolicy: reg.unknownToolPolicy ?? "mutating",
|
|
70595
|
+
unknownToolPolicy: strict ? reg.unknownToolPolicy === "reject" ? "reject" : "mutating" : reg.unknownToolPolicy ?? "mutating",
|
|
70539
70596
|
classify: reg.classify,
|
|
70540
70597
|
binders: reg.binders,
|
|
70541
70598
|
forceReadonly: reg.forceReadonly,
|
|
70542
|
-
failOnUnguardedMutator: reg.failOnUnguardedMutator
|
|
70599
|
+
failOnUnguardedMutator: strict ? true : reg.failOnUnguardedMutator
|
|
70543
70600
|
};
|
|
70601
|
+
const requireCoverage = strict ? "COMPLETE" : input.requireCoverage;
|
|
70544
70602
|
const { tools, report } = (0, tool_registry_js_1.guardToolRegistry)(input.tools, config);
|
|
70545
|
-
if (
|
|
70546
|
-
const requiredRank = coverageRank(
|
|
70603
|
+
if (requireCoverage !== void 0) {
|
|
70604
|
+
const requiredRank = coverageRank(requireCoverage);
|
|
70547
70605
|
const actualRank = coverageRank(report.coverage) ?? -1;
|
|
70548
70606
|
if (requiredRank !== void 0 && actualRank < requiredRank) {
|
|
70549
|
-
throw new Error(`withCodeRifts: requireCoverage not met \u2014 registry coverage '${report.coverage}' is weaker than required '${
|
|
70607
|
+
throw new Error(`withCodeRifts: requireCoverage not met \u2014 registry coverage '${report.coverage}' is weaker than required '${requireCoverage}' (strength ordering COMPLETE > PARTIAL > BYPASSED > UNKNOWN). requireCoverage constrains the REGISTRY tool-boundary surface ONLY; a green construction here is NOT a product-level runtime-inescapability guarantee \u2014 composition_assurance.inescapable_runtime stays false until receipt carry-forward and a freshness-safe prior for write-style calls land.`);
|
|
70550
70608
|
}
|
|
70551
70609
|
}
|
|
70552
70610
|
const compositionInescapableRuntime = report.claim.inescapable_runtime && COMPOSITION_CALL_POLICY_COMPLETE;
|
|
@@ -70561,9 +70619,12 @@ var require_with_coderifts = __commonJS({
|
|
|
70561
70619
|
if (!freshness_resolver_wired) {
|
|
70562
70620
|
residuals.push(RESIDUAL_FRESHNESS_NOT_CONFIGURED);
|
|
70563
70621
|
}
|
|
70564
|
-
if (input.requireConditionalWrite === true) {
|
|
70622
|
+
if (input.requireConditionalWrite === true || strict) {
|
|
70565
70623
|
residuals.push("composition_unconditional_write_under_policy");
|
|
70566
70624
|
}
|
|
70625
|
+
if (strict) {
|
|
70626
|
+
residuals.push(RESIDUAL_CALLS_OUTSIDE_GUARDED_PATH);
|
|
70627
|
+
}
|
|
70567
70628
|
const composition_assurance = {
|
|
70568
70629
|
coverage: "PARTIAL",
|
|
70569
70630
|
inescapable_runtime: compositionInescapableRuntime,
|
|
@@ -71755,7 +71816,8 @@ var require_deploy_gate2 = __commonJS({
|
|
|
71755
71816
|
if (enforcement === "ENFORCING") out.push("bypass_open");
|
|
71756
71817
|
else if (enforcement === "ADVISORY") out.push("deploy_gate_advisory");
|
|
71757
71818
|
else if (enforcement === "ABSENT") out.push("deploy_path_ungated");
|
|
71758
|
-
}
|
|
71819
|
+
}
|
|
71820
|
+
if (change_set_rebound !== true) {
|
|
71759
71821
|
out.push("change_set_not_rebound");
|
|
71760
71822
|
}
|
|
71761
71823
|
return out;
|
|
@@ -71793,8 +71855,8 @@ var require_deploy_gate2 = __commonJS({
|
|
|
71793
71855
|
if (expected_body_hash != null) requiredContext.expected_body_hash = expected_body_hash;
|
|
71794
71856
|
}
|
|
71795
71857
|
const gate = deployGate({ deployTarget: { environment, artifact_id }, receipt, requiredContext });
|
|
71796
|
-
const enforcement_inescapable =
|
|
71797
|
-
const inescapable_deploy =
|
|
71858
|
+
const enforcement_inescapable = attested_enforcement === "ENFORCING" && !!(observed_cd_enforcement && observed_cd_enforcement.bypass_possible === false);
|
|
71859
|
+
const inescapable_deploy = gate.inescapable_deploy === true && change_set_rebound === true;
|
|
71798
71860
|
return {
|
|
71799
71861
|
deploy_check_status: gate.state,
|
|
71800
71862
|
reason: gate.reason,
|
|
@@ -73285,9 +73347,9 @@ generator_detection: true
|
|
|
73285
73347
|
chalk.dim(" (uses YOUR gh credentials; CodeRifts never takes admin rights)."),
|
|
73286
73348
|
chalk.dim(" To attest cross-layer ENFORCING after wiring: coderifts enforce --apply"),
|
|
73287
73349
|
chalk.dim(" (dry-run without --apply; does not auto-flip defaults)."),
|
|
73288
|
-
chalk.dim(" For agent tool-call guarding
|
|
73289
|
-
chalk.dim("
|
|
73290
|
-
chalk.dim(" (
|
|
73350
|
+
chalk.dim(" For agent tool-call guarding: @coderifts/agent-guard requireExecutionStateMatch"),
|
|
73351
|
+
chalk.dim(" defaults ON (absent\u2192true) \u2014 observed drift STOPS. Opt-down: 'warn' (emit, proceed)"),
|
|
73352
|
+
chalk.dim(" or false (proceed-on-drift) \u2014 see: coderifts agent-setup"),
|
|
73291
73353
|
chalk.dim(" Agent-using repo? Run: coderifts agent-setup")
|
|
73292
73354
|
]);
|
|
73293
73355
|
module2.exports = {
|
|
@@ -100000,12 +100062,12 @@ var require_agent_host_files_embedded = __commonJS({
|
|
|
100000
100062
|
"openai-agent-instructions.md"
|
|
100001
100063
|
]);
|
|
100002
100064
|
var AGENT_HOST_FILES = Object.freeze({
|
|
100003
|
-
"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\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',
|
|
100004
|
-
"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\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',
|
|
100005
|
-
".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\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',
|
|
100006
|
-
".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\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',
|
|
100007
|
-
"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\\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',
|
|
100008
|
-
"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\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'
|
|
100065
|
+
"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',
|
|
100066
|
+
"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',
|
|
100067
|
+
".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',
|
|
100068
|
+
".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',
|
|
100069
|
+
"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',
|
|
100070
|
+
"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'
|
|
100009
100071
|
});
|
|
100010
100072
|
module2.exports = { AGENT_HOST_FILES, AGENT_HOST_PATHS };
|
|
100011
100073
|
}
|
|
@@ -100150,13 +100212,14 @@ ${USAGE}` };
|
|
|
100150
100212
|
return { exitCode: 0, code: "OK", outDir, ...summary };
|
|
100151
100213
|
}
|
|
100152
100214
|
var AGENT_SETUP_WARN_TELEMETRY_LINES = Object.freeze([
|
|
100153
|
-
chalk.bold("
|
|
100154
|
-
chalk.dim("
|
|
100155
|
-
chalk.dim(" (
|
|
100156
|
-
chalk.dim("
|
|
100215
|
+
chalk.bold(" Execution-state recheck (guard@8): DEFAULT ON"),
|
|
100216
|
+
chalk.dim(" requireExecutionStateMatch absent/true \u2192 enforce: mismatch \u2192 EXECUTION_STATE_DRIFT"),
|
|
100217
|
+
chalk.dim(" (factory does not run); missing fingerprint/artifacts \u2192 EXECUTION_STATE_UNMEASURABLE (STOP)."),
|
|
100218
|
+
chalk.dim(" Opt-down: requireExecutionStateMatch: 'warn' (emit, then run unenforced on mismatch)"),
|
|
100219
|
+
chalk.dim(" or false (no recheck \u2014 v7 proceed-on-drift). Must be set explicitly."),
|
|
100220
|
+
chalk.dim(" Warn emits (then PROCEEDS \u2014 never blocks in warn mode):"),
|
|
100157
100221
|
chalk.dim(" \xB7 real drift \u2192 execution_state_drift_observed (loud)"),
|
|
100158
100222
|
chalk.dim(" \xB7 missing artifacts/fingerprint \u2192 execution_state_unmeasurable (quiet)"),
|
|
100159
|
-
chalk.dim(" Enforce later with requireExecutionStateMatch: true only when ready."),
|
|
100160
100223
|
chalk.dim(" Merge gate block is separate: coderifts setup-required-check --apply")
|
|
100161
100224
|
]);
|
|
100162
100225
|
module2.exports = {
|
|
@@ -101133,21 +101196,23 @@ var require_claude_hook = __commonJS({
|
|
|
101133
101196
|
"configured contract spec path. Reads JSON context from STDIN.",
|
|
101134
101197
|
"",
|
|
101135
101198
|
"Exit map (Claude Code semantics \u2014 get this exactly right):",
|
|
101136
|
-
" 2 BLOCK \u2014 tool call cancelled (
|
|
101137
|
-
"
|
|
101199
|
+
" 2 BLOCK \u2014 tool call cancelled (BLOCK/STOP, REQUEST_APPROVAL, unrecognised action,",
|
|
101200
|
+
" governance could not run, CONTINUE_WITH_MONITORING without a wired sink)",
|
|
101201
|
+
" 0 allow \u2014 CONTINUE, or CWM with a host-asserted monitoring sink, or non-contract skip",
|
|
101138
101202
|
" 1 NEVER used for security deny (Claude treats exit 1 as non-blocking; action proceeds)",
|
|
101139
101203
|
"",
|
|
101140
|
-
"
|
|
101141
|
-
" no API key
|
|
101142
|
-
"
|
|
101143
|
-
"
|
|
101144
|
-
"
|
|
101145
|
-
"
|
|
101204
|
+
"Fail-closed DEFAULT (exit 2, reason enforce_indeterminate) when governance could not run:",
|
|
101205
|
+
" no API key / API unreachable / disk unreadable / edit-apply failure on the spec path",
|
|
101206
|
+
" Absence of a key is not permission. Explicit opt-out: CODERIFTS_ADVISORY=1|true.",
|
|
101207
|
+
"",
|
|
101208
|
+
"Still exit 0 (nothing to govern): unparseable stdin, missing file_path, non-spec path,",
|
|
101209
|
+
"identical content.",
|
|
101146
101210
|
"",
|
|
101147
|
-
"
|
|
101148
|
-
"
|
|
101149
|
-
"
|
|
101150
|
-
"
|
|
101211
|
+
"CONTINUE_WITH_MONITORING: allow only if the host asserts a sink",
|
|
101212
|
+
" (CODERIFTS_MONITORING_SINK_WIRED=1|true or git config coderifts.monitoringSinkWired).",
|
|
101213
|
+
" Host claim \u2014 not delivery proof (same class as GuardConfig.monitoringSinkWired).",
|
|
101214
|
+
"",
|
|
101215
|
+
"CODERIFTS_STRICT=1|true: same fail-closed as default; cannot be weakened by ADVISORY.",
|
|
101151
101216
|
"",
|
|
101152
101217
|
"Spec path (same source as git pre-push hook):",
|
|
101153
101218
|
" git config coderifts.specPath (default: api/openapi.yaml)",
|
|
@@ -101158,21 +101223,56 @@ var require_claude_hook = __commonJS({
|
|
|
101158
101223
|
"",
|
|
101159
101224
|
"Push-time equivalent: coderifts hook install (git exit 1 on BLOCK)."
|
|
101160
101225
|
].join("\n");
|
|
101161
|
-
function
|
|
101162
|
-
const v = env && env
|
|
101226
|
+
function isEnvFlag(env, name) {
|
|
101227
|
+
const v = env && env[name];
|
|
101163
101228
|
if (v == null || v === "") return false;
|
|
101164
101229
|
const s = String(v).trim().toLowerCase();
|
|
101165
101230
|
return s === "1" || s === "true";
|
|
101166
101231
|
}
|
|
101167
|
-
function
|
|
101232
|
+
function isStrictMode(env = process.env) {
|
|
101233
|
+
return isEnvFlag(env, "CODERIFTS_STRICT");
|
|
101234
|
+
}
|
|
101235
|
+
function isAdvisoryMode(env = process.env) {
|
|
101236
|
+
return isEnvFlag(env, "CODERIFTS_ADVISORY");
|
|
101237
|
+
}
|
|
101238
|
+
function isMonitoringSinkWired({ env = process.env, deps = {}, result = null } = {}) {
|
|
101239
|
+
if (deps && deps.monitoringSinkWired === true) return true;
|
|
101240
|
+
if (isEnvFlag(env, "CODERIFTS_MONITORING_SINK_WIRED")) return true;
|
|
101241
|
+
const git = readGitConfig("coderifts.monitoringSinkWired", deps);
|
|
101242
|
+
if (git) {
|
|
101243
|
+
const s = String(git).trim().toLowerCase();
|
|
101244
|
+
if (s === "1" || s === "true") return true;
|
|
101245
|
+
}
|
|
101246
|
+
if (result && result.monitoringSinkWired === true) return true;
|
|
101247
|
+
const dr = result && result.decision_result;
|
|
101248
|
+
if (dr && typeof dr === "object" && dr.monitoringSinkWired === true) return true;
|
|
101249
|
+
return false;
|
|
101250
|
+
}
|
|
101251
|
+
function failClosedOrAdvisory({ advisory, strict, site, softMsg, why, errLog }) {
|
|
101252
|
+
if (advisory && !strict) {
|
|
101253
|
+
errLog(`${softMsg} (CODERIFTS_ADVISORY)`);
|
|
101254
|
+
return { exitCode: 0, reason: site, site };
|
|
101255
|
+
}
|
|
101168
101256
|
if (strict) {
|
|
101169
101257
|
errLog(
|
|
101170
101258
|
`CodeRifts claude-hook: CODERIFTS_STRICT: governance could not run (${why}) \u2014 blocking. Set a key / restore network, or unset CODERIFTS_STRICT.`
|
|
101171
101259
|
);
|
|
101172
|
-
return { exitCode: 2, reason, strictBlocked: true };
|
|
101260
|
+
return { exitCode: 2, reason: "enforce_indeterminate", site, strictBlocked: true };
|
|
101173
101261
|
}
|
|
101174
|
-
errLog(
|
|
101175
|
-
|
|
101262
|
+
errLog(
|
|
101263
|
+
`CodeRifts claude-hook: governance could not run (${why}) \u2014 blocking. Set CODERIFTS_ADVISORY=1 to allow without governance (explicit opt-out).`
|
|
101264
|
+
);
|
|
101265
|
+
return { exitCode: 2, reason: "enforce_indeterminate", site };
|
|
101266
|
+
}
|
|
101267
|
+
function softOrStrictBlock({ strict, reason, softMsg, why, errLog }) {
|
|
101268
|
+
return failClosedOrAdvisory({
|
|
101269
|
+
advisory: false,
|
|
101270
|
+
strict: !!strict,
|
|
101271
|
+
site: reason,
|
|
101272
|
+
softMsg,
|
|
101273
|
+
why,
|
|
101274
|
+
errLog
|
|
101275
|
+
});
|
|
101176
101276
|
}
|
|
101177
101277
|
function readGitConfig(key, deps = {}) {
|
|
101178
101278
|
const run = deps.execSync || execSync;
|
|
@@ -101279,7 +101379,7 @@ var require_claude_hook = __commonJS({
|
|
|
101279
101379
|
return { ok: false, reason: `unsupported tool_name for content derive: ${name}` };
|
|
101280
101380
|
}
|
|
101281
101381
|
function mapDecisionSeverity(result) {
|
|
101282
|
-
const d = result && typeof result === "object" ? result : {};
|
|
101382
|
+
const d = result && typeof result === "object" && !Array.isArray(result) ? result : {};
|
|
101283
101383
|
let ea = null;
|
|
101284
101384
|
const dr = d.decision_result;
|
|
101285
101385
|
if (dr && typeof dr === "object" && typeof dr.execution_action === "string") {
|
|
@@ -101287,20 +101387,33 @@ var require_claude_hook = __commonJS({
|
|
|
101287
101387
|
} else if (typeof d.execution_action === "string") {
|
|
101288
101388
|
ea = d.execution_action;
|
|
101289
101389
|
}
|
|
101390
|
+
const hasDecision = d.omega_decision != null && d.omega_decision !== "" || d.decision != null && d.decision !== "" || dr && typeof dr === "object" && dr.execution_action;
|
|
101391
|
+
if (d.error && !hasDecision && (ea == null || ea === "")) {
|
|
101392
|
+
return {
|
|
101393
|
+
severity: "INDETERMINATE",
|
|
101394
|
+
decision: null,
|
|
101395
|
+
decisionId: null,
|
|
101396
|
+
executionAction: null
|
|
101397
|
+
};
|
|
101398
|
+
}
|
|
101290
101399
|
let severity;
|
|
101291
101400
|
if (ea != null && ea !== "") {
|
|
101292
101401
|
if (!CLOSED_ACTIONS.has(ea)) {
|
|
101293
101402
|
severity = "UNKNOWN";
|
|
101294
|
-
} else if (ea === "CONTINUE"
|
|
101403
|
+
} else if (ea === "CONTINUE") {
|
|
101295
101404
|
severity = "ALLOW";
|
|
101405
|
+
} else if (ea === "CONTINUE_WITH_MONITORING") {
|
|
101406
|
+
severity = "MONITOR";
|
|
101296
101407
|
} else if (ea === "STOP") {
|
|
101297
101408
|
severity = "BLOCK";
|
|
101298
101409
|
} else {
|
|
101299
101410
|
severity = "REQUIRE_APPROVAL";
|
|
101300
101411
|
}
|
|
101301
101412
|
} else {
|
|
101302
|
-
const od = d.omega_decision || d.decision
|
|
101303
|
-
if (od === "
|
|
101413
|
+
const od = d.omega_decision || d.decision;
|
|
101414
|
+
if (od == null || od === "") {
|
|
101415
|
+
severity = "INDETERMINATE";
|
|
101416
|
+
} else if (od === "BLOCK") severity = "BLOCK";
|
|
101304
101417
|
else if (od === "REQUIRE_APPROVAL") severity = "REQUIRE_APPROVAL";
|
|
101305
101418
|
else if (od === "WARN") severity = "WARN";
|
|
101306
101419
|
else severity = "ALLOW";
|
|
@@ -101309,7 +101422,7 @@ var require_claude_hook = __commonJS({
|
|
|
101309
101422
|
const decisionId = dr && dr.decision_id || d.decision_id || null;
|
|
101310
101423
|
return {
|
|
101311
101424
|
severity,
|
|
101312
|
-
decision: decision != null ? String(decision) : null,
|
|
101425
|
+
decision: decision != null && decision !== "" ? String(decision) : null,
|
|
101313
101426
|
decisionId: decisionId != null ? String(decisionId) : null,
|
|
101314
101427
|
executionAction: ea
|
|
101315
101428
|
};
|
|
@@ -101329,11 +101442,13 @@ var require_claude_hook = __commonJS({
|
|
|
101329
101442
|
const cwd = deps.cwd || process.cwd();
|
|
101330
101443
|
const env = deps.env || process.env;
|
|
101331
101444
|
const strict = isStrictMode(env);
|
|
101445
|
+
const advisory = isAdvisoryMode(env);
|
|
101332
101446
|
const apiKey = resolveApiKey({ ...deps, cwd, env });
|
|
101333
101447
|
if (!apiKey) {
|
|
101334
|
-
return
|
|
101448
|
+
return failClosedOrAdvisory({
|
|
101449
|
+
advisory,
|
|
101335
101450
|
strict,
|
|
101336
|
-
|
|
101451
|
+
site: "missing_api_key",
|
|
101337
101452
|
why: "no API key",
|
|
101338
101453
|
softMsg: "CodeRifts claude-hook: no API key (coderifts login / CODERIFTS_API_KEY / git config coderifts.apiKey) \u2014 allowing",
|
|
101339
101454
|
errLog
|
|
@@ -101361,9 +101476,10 @@ var require_claude_hook = __commonJS({
|
|
|
101361
101476
|
try {
|
|
101362
101477
|
diskBefore = readFile(absPath, "utf8");
|
|
101363
101478
|
} catch (e) {
|
|
101364
|
-
return
|
|
101479
|
+
return failClosedOrAdvisory({
|
|
101480
|
+
advisory,
|
|
101365
101481
|
strict,
|
|
101366
|
-
|
|
101482
|
+
site: "disk_unreadable",
|
|
101367
101483
|
why: `cannot read contract file ${absPath}`,
|
|
101368
101484
|
softMsg: `CodeRifts claude-hook: cannot read ${absPath} \u2014 allowing (soft)`,
|
|
101369
101485
|
errLog
|
|
@@ -101372,9 +101488,10 @@ var require_claude_hook = __commonJS({
|
|
|
101372
101488
|
}
|
|
101373
101489
|
const derived = deriveAfterContent(toolName, toolInput, diskBefore);
|
|
101374
101490
|
if (!derived.ok) {
|
|
101375
|
-
return
|
|
101491
|
+
return failClosedOrAdvisory({
|
|
101492
|
+
advisory,
|
|
101376
101493
|
strict,
|
|
101377
|
-
|
|
101494
|
+
site: "edit_apply_failed",
|
|
101378
101495
|
why: derived.reason,
|
|
101379
101496
|
softMsg: `CodeRifts claude-hook: ${derived.reason} \u2014 allowing (soft; never guess edit apply)`,
|
|
101380
101497
|
errLog
|
|
@@ -101391,9 +101508,10 @@ var require_claude_hook = __commonJS({
|
|
|
101391
101508
|
});
|
|
101392
101509
|
} catch (e) {
|
|
101393
101510
|
const msg = e && e.message ? String(e.message) : "request failed";
|
|
101394
|
-
return
|
|
101511
|
+
return failClosedOrAdvisory({
|
|
101512
|
+
advisory,
|
|
101395
101513
|
strict,
|
|
101396
|
-
|
|
101514
|
+
site: "api_unreachable",
|
|
101397
101515
|
why: `API unreachable: ${msg}`,
|
|
101398
101516
|
softMsg: `CodeRifts claude-hook: API unreachable (${msg}) \u2014 allowing (soft; availability must not brick the editor)`,
|
|
101399
101517
|
errLog
|
|
@@ -101403,6 +101521,18 @@ var require_claude_hook = __commonJS({
|
|
|
101403
101521
|
const idPart = mapped.decisionId ? ` decision_id=${mapped.decisionId}` : "";
|
|
101404
101522
|
const decPart = mapped.decision ? ` decision=${mapped.decision}` : "";
|
|
101405
101523
|
const eaPart = mapped.executionAction ? ` execution_action=${mapped.executionAction}` : "";
|
|
101524
|
+
if (mapped.severity === "INDETERMINATE") {
|
|
101525
|
+
errLog(
|
|
101526
|
+
"CodeRifts claude-hook: BLOCKED (indeterminate response \u2014 no execution_action and no decision; not permission)"
|
|
101527
|
+
);
|
|
101528
|
+
return {
|
|
101529
|
+
exitCode: 2,
|
|
101530
|
+
reason: "indeterminate",
|
|
101531
|
+
severity: "INDETERMINATE",
|
|
101532
|
+
decision: mapped.decision,
|
|
101533
|
+
decisionId: mapped.decisionId
|
|
101534
|
+
};
|
|
101535
|
+
}
|
|
101406
101536
|
if (mapped.severity === "BLOCK" || mapped.severity === "UNKNOWN") {
|
|
101407
101537
|
errLog(
|
|
101408
101538
|
`CodeRifts claude-hook: BLOCKED${decPart}${eaPart}${idPart}` + (mapped.severity === "UNKNOWN" ? " (unrecognised execution_action)" : "")
|
|
@@ -101415,16 +101545,40 @@ var require_claude_hook = __commonJS({
|
|
|
101415
101545
|
decisionId: mapped.decisionId
|
|
101416
101546
|
};
|
|
101417
101547
|
}
|
|
101418
|
-
if (mapped.severity === "REQUIRE_APPROVAL"
|
|
101419
|
-
errLog(
|
|
101548
|
+
if (mapped.severity === "REQUIRE_APPROVAL") {
|
|
101549
|
+
errLog(
|
|
101550
|
+
`CodeRifts claude-hook: BLOCKED approval_required${decPart}${eaPart}${idPart}`
|
|
101551
|
+
);
|
|
101420
101552
|
return {
|
|
101421
|
-
exitCode:
|
|
101422
|
-
reason: "
|
|
101553
|
+
exitCode: 2,
|
|
101554
|
+
reason: "approval_required",
|
|
101423
101555
|
severity: mapped.severity,
|
|
101424
101556
|
decision: mapped.decision,
|
|
101425
101557
|
decisionId: mapped.decisionId
|
|
101426
101558
|
};
|
|
101427
101559
|
}
|
|
101560
|
+
if (mapped.severity === "MONITOR" || mapped.severity === "WARN") {
|
|
101561
|
+
const sinkWired = isMonitoringSinkWired({ env, deps, result });
|
|
101562
|
+
if (!sinkWired) {
|
|
101563
|
+
errLog(
|
|
101564
|
+
`CodeRifts claude-hook: BLOCKED monitoring_unwired${decPart}${eaPart}${idPart} \u2014 CONTINUE_WITH_MONITORING requires CODERIFTS_MONITORING_SINK_WIRED=1 (host assertion; not delivery proof)`
|
|
101565
|
+
);
|
|
101566
|
+
return {
|
|
101567
|
+
exitCode: 2,
|
|
101568
|
+
reason: "monitoring_unwired",
|
|
101569
|
+
severity: mapped.severity === "WARN" ? "MONITOR" : mapped.severity,
|
|
101570
|
+
decision: mapped.decision,
|
|
101571
|
+
decisionId: mapped.decisionId
|
|
101572
|
+
};
|
|
101573
|
+
}
|
|
101574
|
+
return {
|
|
101575
|
+
exitCode: 0,
|
|
101576
|
+
reason: "allow",
|
|
101577
|
+
severity: mapped.severity === "WARN" ? "MONITOR" : mapped.severity,
|
|
101578
|
+
decision: mapped.decision,
|
|
101579
|
+
decisionId: mapped.decisionId
|
|
101580
|
+
};
|
|
101581
|
+
}
|
|
101428
101582
|
return {
|
|
101429
101583
|
exitCode: 0,
|
|
101430
101584
|
reason: "allow",
|
|
@@ -101442,7 +101596,11 @@ var require_claude_hook = __commonJS({
|
|
|
101442
101596
|
resolveApiKey,
|
|
101443
101597
|
resolveSpecPath,
|
|
101444
101598
|
readGitConfig,
|
|
101599
|
+
isEnvFlag,
|
|
101445
101600
|
isStrictMode,
|
|
101601
|
+
isAdvisoryMode,
|
|
101602
|
+
isMonitoringSinkWired,
|
|
101603
|
+
failClosedOrAdvisory,
|
|
101446
101604
|
softOrStrictBlock,
|
|
101447
101605
|
DEFAULT_SPEC_PATH,
|
|
101448
101606
|
CLOSED_ACTIONS,
|
|
@@ -103446,7 +103604,7 @@ ${USAGE}
|
|
|
103446
103604
|
}
|
|
103447
103605
|
});
|
|
103448
103606
|
program.command("claude-hook").description(
|
|
103449
|
-
"Claude Code PreToolUse gate: block contract-touching Write|Edit|MultiEdit on BLOCK/STOP (exit 2).
|
|
103607
|
+
"Claude Code PreToolUse gate: block contract-touching Write|Edit|MultiEdit on BLOCK/STOP/REQUEST_APPROVAL (exit 2). Fail-closed when governance cannot run; CODERIFTS_ADVISORY=1 is the explicit soft opt-out."
|
|
103450
103608
|
).addHelpText("after", () => {
|
|
103451
103609
|
const { USAGE } = require_claude_hook();
|
|
103452
103610
|
return `
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coderifts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
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",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"bin/",
|
|
14
14
|
"scripts/",
|
|
15
15
|
"README.md",
|
|
16
|
+
"CHANGELOG.md",
|
|
16
17
|
"corpus/"
|
|
17
18
|
],
|
|
18
19
|
"keywords": [
|
|
@@ -44,7 +45,7 @@
|
|
|
44
45
|
"test": "node --test test/*.test.js"
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
47
|
-
"@coderifts/agent-guard": "^
|
|
48
|
+
"@coderifts/agent-guard": "^8.1.1",
|
|
48
49
|
"chalk": "^4.1.2",
|
|
49
50
|
"cli-table3": "^0.6.4",
|
|
50
51
|
"commander": "^12.0.0",
|
|
@@ -5,18 +5,19 @@
|
|
|
5
5
|
* CLI release gate (prepublishOnly): refuse to publish if the declared
|
|
6
6
|
* @coderifts/agent-guard range floors below the minimum acceptable major.
|
|
7
7
|
*
|
|
8
|
-
* Honest scope: compares the dependency *range floor* (e.g. ^
|
|
8
|
+
* Honest scope: compares the dependency *range floor* (e.g. ^8.1.1 → 8) to a
|
|
9
9
|
* pinned constant. Does not call npm registry. Optional: if node_modules has a
|
|
10
10
|
* resolved package, also fail when its major is below the floor (stale install).
|
|
11
11
|
*
|
|
12
12
|
* Why: evening audit 2.4 — CLI sat on ^1.6.0 while published guard is 6.x.
|
|
13
|
+
* 4.0.0: floor raised to 8 (deployGate inescapable_deploy includes fingerprint rebound).
|
|
13
14
|
*/
|
|
14
15
|
|
|
15
16
|
const fs = require('fs');
|
|
16
17
|
const path = require('path');
|
|
17
18
|
|
|
18
19
|
/** Minimum acceptable major for @coderifts/agent-guard (published line). */
|
|
19
|
-
const MIN_GUARD_MAJOR =
|
|
20
|
+
const MIN_GUARD_MAJOR = 8;
|
|
20
21
|
const DEP = '@coderifts/agent-guard';
|
|
21
22
|
|
|
22
23
|
function fail(msg) {
|