coderifts 1.9.0 → 2.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/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: "1.9.0",
3010
+ version: "2.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",
@@ -3055,7 +3055,7 @@ var require_package = __commonJS({
3055
3055
  "cli-table3": "^0.6.4",
3056
3056
  commander: "^12.0.0",
3057
3057
  inquirer: "^8.2.6",
3058
- "js-yaml": "^4.2.0",
3058
+ "js-yaml": "^4.3.1",
3059
3059
  "openapi-diff": "^0.24.1",
3060
3060
  ora: "^5.4.1"
3061
3061
  },
@@ -3063,7 +3063,9 @@ var require_package = __commonJS({
3063
3063
  "z-schema": "^7.2.0",
3064
3064
  "json-schema-ref-parser": "npm:@apidevtools/json-schema-ref-parser@^11.7.3",
3065
3065
  "form-data": "^4.0.6",
3066
- axios: ">=1.18.0"
3066
+ axios: ">=1.18.0",
3067
+ "fast-uri": ">=3.1.5",
3068
+ "brace-expansion": "5.0.9"
3067
3069
  },
3068
3070
  devDependencies: {
3069
3071
  esbuild: "^0.28.1"
@@ -4367,7 +4369,7 @@ var require_templates = __commonJS({
4367
4369
  if (!Number.isNaN(number)) {
4368
4370
  results.push(number);
4369
4371
  } else if (matches = chunk.match(STRING_REGEX)) {
4370
- results.push(matches[2].replace(ESCAPE_REGEX, (m, escape2, character) => escape2 ? unescape2(escape2) : character));
4372
+ results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape2(escape) : character));
4371
4373
  } else {
4372
4374
  throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
4373
4375
  }
@@ -11256,7 +11258,7 @@ var require_omap = __commonJS({
11256
11258
  var _toString = Object.prototype.toString;
11257
11259
  function resolveYamlOmap(data) {
11258
11260
  if (data === null) return true;
11259
- const objectKeys = [];
11261
+ const objectKeys = {};
11260
11262
  const object = data;
11261
11263
  for (let index = 0, length = object.length; index < length; index += 1) {
11262
11264
  const pair = object[index];
@@ -11270,8 +11272,8 @@ var require_omap = __commonJS({
11270
11272
  }
11271
11273
  }
11272
11274
  if (!pairHasKey) return false;
11273
- if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
11274
- else return false;
11275
+ if (_hasOwnProperty.call(objectKeys, pairKey)) return false;
11276
+ Object.defineProperty(objectKeys, pairKey, { value: true });
11275
11277
  }
11276
11278
  return true;
11277
11279
  }
@@ -24778,7 +24780,7 @@ var require_lodash = __commonJS({
24778
24780
  position -= target.length;
24779
24781
  return position >= 0 && string.slice(position, end) == target;
24780
24782
  }
24781
- function escape2(string) {
24783
+ function escape(string) {
24782
24784
  string = toString(string);
24783
24785
  return string && reHasUnescapedHtml.test(string) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string;
24784
24786
  }
@@ -25389,7 +25391,7 @@ var require_lodash = __commonJS({
25389
25391
  lodash.divide = divide;
25390
25392
  lodash.endsWith = endsWith;
25391
25393
  lodash.eq = eq;
25392
- lodash.escape = escape2;
25394
+ lodash.escape = escape;
25393
25395
  lodash.escapeRegExp = escapeRegExp;
25394
25396
  lodash.every = every;
25395
25397
  lodash.find = find;
@@ -29363,6 +29365,7 @@ var require_utils2 = __commonJS({
29363
29365
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
29364
29366
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
29365
29367
  var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
29368
+ var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/?]$/iu);
29366
29369
  function stringArrayToHexStripped(input) {
29367
29370
  let acc = "";
29368
29371
  let code = 0;
@@ -29505,7 +29508,7 @@ var require_utils2 = __commonJS({
29505
29508
  continue;
29506
29509
  }
29507
29510
  } else if (input[0] === "/") {
29508
- if (input[1] === "." || input[1] === "/") {
29511
+ if (input[1] === ".") {
29509
29512
  output.push("/");
29510
29513
  break;
29511
29514
  }
@@ -29587,10 +29590,30 @@ var require_utils2 = __commonJS({
29587
29590
  }
29588
29591
  return output;
29589
29592
  }
29593
+ var BYTE_HEX = new Array(256);
29594
+ {
29595
+ const HEX_DIGITS = "0123456789ABCDEF";
29596
+ for (let i = 0; i < 256; i++) {
29597
+ BYTE_HEX[i] = "%" + HEX_DIGITS[i >> 4] + HEX_DIGITS[i & 15];
29598
+ }
29599
+ }
29600
+ function isEscapeSafe(cp) {
29601
+ return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
29602
+ }
29603
+ function percentEncodeNonAscii(cp) {
29604
+ if (cp < 2048) {
29605
+ return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
29606
+ }
29607
+ if (cp < 65536) {
29608
+ return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
29609
+ }
29610
+ return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
29611
+ }
29590
29612
  function normalizePathEncoding(input) {
29591
29613
  let output = "";
29592
29614
  for (let i = 0; i < input.length; i++) {
29593
- if (input[i] === "%" && i + 2 < input.length) {
29615
+ const ch = input[i];
29616
+ if (ch === "%" && i + 2 < input.length) {
29594
29617
  const hex = input.slice(i + 1, i + 3);
29595
29618
  if (isHexPair(hex)) {
29596
29619
  const normalizedHex = hex.toUpperCase();
@@ -29604,10 +29627,66 @@ var require_utils2 = __commonJS({
29604
29627
  continue;
29605
29628
  }
29606
29629
  }
29607
- if (isPathCharacter(input[i])) {
29608
- output += input[i];
29630
+ if (isPathCharacter(ch)) {
29631
+ output += ch;
29632
+ } else {
29633
+ const code = input.charCodeAt(i);
29634
+ if (code < 128) {
29635
+ output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
29636
+ } else if (code < 55296 || code > 57343) {
29637
+ output += percentEncodeNonAscii(code);
29638
+ } else if (code <= 56319 && i + 1 < input.length) {
29639
+ const low = input.charCodeAt(i + 1);
29640
+ if (low >= 56320 && low <= 57343) {
29641
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
29642
+ i++;
29643
+ } else {
29644
+ output += percentEncodeNonAscii(65533);
29645
+ }
29646
+ } else {
29647
+ output += percentEncodeNonAscii(65533);
29648
+ }
29649
+ }
29650
+ }
29651
+ return output;
29652
+ }
29653
+ function normalizeQueryFragmentEncoding(input) {
29654
+ let output = "";
29655
+ for (let i = 0; i < input.length; i++) {
29656
+ const ch = input[i];
29657
+ if (ch === "%" && i + 2 < input.length) {
29658
+ const hex = input.slice(i + 1, i + 3);
29659
+ if (isHexPair(hex)) {
29660
+ const normalizedHex = hex.toUpperCase();
29661
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
29662
+ if (isUnreserved(decoded)) {
29663
+ output += decoded;
29664
+ } else {
29665
+ output += "%" + normalizedHex;
29666
+ }
29667
+ i += 2;
29668
+ continue;
29669
+ }
29670
+ }
29671
+ if (isQueryFragmentCharacter(ch)) {
29672
+ output += ch;
29609
29673
  } else {
29610
- output += escape(input[i]);
29674
+ const code = input.charCodeAt(i);
29675
+ if (code < 128) {
29676
+ output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
29677
+ } else if (code < 55296 || code > 57343) {
29678
+ output += percentEncodeNonAscii(code);
29679
+ } else if (code <= 56319 && i + 1 < input.length) {
29680
+ const low = input.charCodeAt(i + 1);
29681
+ if (low >= 56320 && low <= 57343) {
29682
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
29683
+ i++;
29684
+ } else {
29685
+ output += percentEncodeNonAscii(65533);
29686
+ }
29687
+ } else {
29688
+ output += percentEncodeNonAscii(65533);
29689
+ }
29611
29690
  }
29612
29691
  }
29613
29692
  return output;
@@ -29615,7 +29694,8 @@ var require_utils2 = __commonJS({
29615
29694
  function escapePreservingEscapes(input) {
29616
29695
  let output = "";
29617
29696
  for (let i = 0; i < input.length; i++) {
29618
- if (input[i] === "%" && i + 2 < input.length) {
29697
+ const ch = input[i];
29698
+ if (ch === "%" && i + 2 < input.length) {
29619
29699
  const hex = input.slice(i + 1, i + 3);
29620
29700
  if (isHexPair(hex)) {
29621
29701
  output += "%" + hex.toUpperCase();
@@ -29623,7 +29703,22 @@ var require_utils2 = __commonJS({
29623
29703
  continue;
29624
29704
  }
29625
29705
  }
29626
- output += escape(input[i]);
29706
+ const code = input.charCodeAt(i);
29707
+ if (code < 128) {
29708
+ output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
29709
+ } else if (code < 55296 || code > 57343) {
29710
+ output += percentEncodeNonAscii(code);
29711
+ } else if (code <= 56319 && i + 1 < input.length) {
29712
+ const low = input.charCodeAt(i + 1);
29713
+ if (low >= 56320 && low <= 57343) {
29714
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
29715
+ i++;
29716
+ } else {
29717
+ output += percentEncodeNonAscii(65533);
29718
+ }
29719
+ } else {
29720
+ output += percentEncodeNonAscii(65533);
29721
+ }
29627
29722
  }
29628
29723
  return output;
29629
29724
  }
@@ -29657,6 +29752,7 @@ var require_utils2 = __commonJS({
29657
29752
  reescapeHostDelimiters,
29658
29753
  normalizePercentEncoding,
29659
29754
  normalizePathEncoding,
29755
+ normalizeQueryFragmentEncoding,
29660
29756
  escapePreservingEscapes,
29661
29757
  removeDotSegments,
29662
29758
  isIPv4,
@@ -29881,7 +29977,7 @@ var require_schemes = __commonJS({
29881
29977
  var require_fast_uri = __commonJS({
29882
29978
  "node_modules/fast-uri/index.js"(exports2, module2) {
29883
29979
  "use strict";
29884
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils2();
29980
+ var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, normalizeQueryFragmentEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils2();
29885
29981
  var { SCHEMES, getSchemeHandler } = require_schemes();
29886
29982
  function normalize(uri, options) {
29887
29983
  if (typeof uri === "string") {
@@ -29895,7 +29991,12 @@ var require_fast_uri = __commonJS({
29895
29991
  }
29896
29992
  function resolve(baseURI, relativeURI, options) {
29897
29993
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
29898
- const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
29994
+ const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
29995
+ const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
29996
+ if (baseMalformed || relativeMalformed) {
29997
+ throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
29998
+ }
29999
+ const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
29899
30000
  schemelessOptions.skipEscape = true;
29900
30001
  return serialize(resolved, schemelessOptions);
29901
30002
  }
@@ -30021,6 +30122,7 @@ var require_fast_uri = __commonJS({
30021
30122
  }
30022
30123
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
30023
30124
  var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
30125
+ var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
30024
30126
  function getParseError(parsed, matches) {
30025
30127
  if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
30026
30128
  return 'URI path must start with "/" when authority is present.';
@@ -30055,9 +30157,23 @@ var require_fast_uri = __commonJS({
30055
30157
  parsed.error = "URI authority must not contain a literal backslash.";
30056
30158
  malformedAuthorityOrPort = true;
30057
30159
  }
30160
+ const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION);
30161
+ if (introducerMatch !== null) {
30162
+ const region = introducerMatch[1];
30163
+ const normalizedRegion = region.replace(/[\t\n\r]/g, "");
30164
+ if (normalizedRegion.length >= 2) {
30165
+ if (normalizedRegion.slice(0, 2) !== "//") {
30166
+ parsed.error = parsed.error || "URI authority must not contain a literal backslash.";
30167
+ malformedAuthorityOrPort = true;
30168
+ } else if (region.length !== normalizedRegion.length) {
30169
+ parsed.error = parsed.error || "URI authority introducer must not contain whitespace.";
30170
+ malformedAuthorityOrPort = true;
30171
+ }
30172
+ }
30173
+ }
30058
30174
  const matches = uri.match(URI_PARSE);
30059
30175
  if (matches) {
30060
- parsed.scheme = matches[1];
30176
+ parsed.scheme = matches[1] === void 0 ? void 0 : matches[1].toLowerCase();
30061
30177
  parsed.userinfo = matches[3];
30062
30178
  parsed.host = matches[4];
30063
30179
  parsed.port = parseInt(matches[5], 10);
@@ -30116,12 +30232,11 @@ var require_fast_uri = __commonJS({
30116
30232
  if (parsed.path) {
30117
30233
  parsed.path = normalizePathEncoding(parsed.path);
30118
30234
  }
30235
+ if (parsed.query) {
30236
+ parsed.query = normalizeQueryFragmentEncoding(parsed.query);
30237
+ }
30119
30238
  if (parsed.fragment) {
30120
- try {
30121
- parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
30122
- } catch {
30123
- parsed.error = parsed.error || "URI malformed";
30124
- }
30239
+ parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
30125
30240
  }
30126
30241
  }
30127
30242
  if (schemeHandler && schemeHandler.parse) {
@@ -65406,9 +65521,9 @@ var require_diff = __commonJS({
65406
65521
  }
65407
65522
  });
65408
65523
 
65409
- // ../../node_modules/@coderifts/sdk/dist/cjs/errors.js
65524
+ // node_modules/@coderifts/sdk/dist/cjs/errors.js
65410
65525
  var require_errors5 = __commonJS({
65411
- "../../node_modules/@coderifts/sdk/dist/cjs/errors.js"(exports2) {
65526
+ "node_modules/@coderifts/sdk/dist/cjs/errors.js"(exports2) {
65412
65527
  "use strict";
65413
65528
  Object.defineProperty(exports2, "__esModule", { value: true });
65414
65529
  exports2.AuthError = exports2.RateLimitError = exports2.TimeoutError = exports2.ApiError = exports2.CodeRiftsError = void 0;
@@ -65458,9 +65573,9 @@ var require_errors5 = __commonJS({
65458
65573
  }
65459
65574
  });
65460
65575
 
65461
- // ../../node_modules/@coderifts/sdk/dist/cjs/client.js
65576
+ // node_modules/@coderifts/sdk/dist/cjs/client.js
65462
65577
  var require_client = __commonJS({
65463
- "../../node_modules/@coderifts/sdk/dist/cjs/client.js"(exports2) {
65578
+ "node_modules/@coderifts/sdk/dist/cjs/client.js"(exports2) {
65464
65579
  "use strict";
65465
65580
  Object.defineProperty(exports2, "__esModule", { value: true });
65466
65581
  exports2.CodeRifts = void 0;
@@ -65708,9 +65823,9 @@ var require_client = __commonJS({
65708
65823
  }
65709
65824
  });
65710
65825
 
65711
- // ../../node_modules/@coderifts/sdk/dist/cjs/decision.js
65826
+ // node_modules/@coderifts/sdk/dist/cjs/decision.js
65712
65827
  var require_decision = __commonJS({
65713
- "../../node_modules/@coderifts/sdk/dist/cjs/decision.js"(exports2) {
65828
+ "node_modules/@coderifts/sdk/dist/cjs/decision.js"(exports2) {
65714
65829
  "use strict";
65715
65830
  Object.defineProperty(exports2, "__esModule", { value: true });
65716
65831
  exports2.readDecision = readDecision;
@@ -65756,9 +65871,9 @@ var require_decision = __commonJS({
65756
65871
  }
65757
65872
  });
65758
65873
 
65759
- // ../../node_modules/@coderifts/sdk/dist/cjs/index.js
65874
+ // node_modules/@coderifts/sdk/dist/cjs/index.js
65760
65875
  var require_cjs3 = __commonJS({
65761
- "../../node_modules/@coderifts/sdk/dist/cjs/index.js"(exports2) {
65876
+ "node_modules/@coderifts/sdk/dist/cjs/index.js"(exports2) {
65762
65877
  "use strict";
65763
65878
  Object.defineProperty(exports2, "__esModule", { value: true });
65764
65879
  exports2.readDecision = exports2.AuthError = exports2.RateLimitError = exports2.TimeoutError = exports2.ApiError = exports2.CodeRiftsError = exports2.CodeRifts = void 0;
@@ -65789,9 +65904,9 @@ var require_cjs3 = __commonJS({
65789
65904
  }
65790
65905
  });
65791
65906
 
65792
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/detector.js
65907
+ // node_modules/@coderifts/agent-guard/dist/cjs/detector.js
65793
65908
  var require_detector = __commonJS({
65794
- "../../node_modules/@coderifts/agent-guard/dist/cjs/detector.js"(exports2) {
65909
+ "node_modules/@coderifts/agent-guard/dist/cjs/detector.js"(exports2) {
65795
65910
  "use strict";
65796
65911
  Object.defineProperty(exports2, "__esModule", { value: true });
65797
65912
  exports2.builtinDetector = exports2.DETECTOR_VERSION = void 0;
@@ -66322,9 +66437,9 @@ var require_detector = __commonJS({
66322
66437
  }
66323
66438
  });
66324
66439
 
66325
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/receipt-binding.js
66440
+ // node_modules/@coderifts/agent-guard/dist/cjs/receipt-binding.js
66326
66441
  var require_receipt_binding = __commonJS({
66327
- "../../node_modules/@coderifts/agent-guard/dist/cjs/receipt-binding.js"(exports2) {
66442
+ "node_modules/@coderifts/agent-guard/dist/cjs/receipt-binding.js"(exports2) {
66328
66443
  "use strict";
66329
66444
  Object.defineProperty(exports2, "__esModule", { value: true });
66330
66445
  exports2.canonicalJson = canonicalJson;
@@ -66396,9 +66511,9 @@ var require_receipt_binding = __commonJS({
66396
66511
  }
66397
66512
  });
66398
66513
 
66399
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/enforcement-gate.js
66514
+ // node_modules/@coderifts/agent-guard/dist/cjs/enforcement-gate.js
66400
66515
  var require_enforcement_gate = __commonJS({
66401
- "../../node_modules/@coderifts/agent-guard/dist/cjs/enforcement-gate.js"(exports2) {
66516
+ "node_modules/@coderifts/agent-guard/dist/cjs/enforcement-gate.js"(exports2) {
66402
66517
  "use strict";
66403
66518
  Object.defineProperty(exports2, "__esModule", { value: true });
66404
66519
  exports2.computeArtifactDigest = computeArtifactDigest;
@@ -66472,9 +66587,9 @@ var require_enforcement_gate = __commonJS({
66472
66587
  }
66473
66588
  });
66474
66589
 
66475
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/guard.js
66590
+ // node_modules/@coderifts/agent-guard/dist/cjs/guard.js
66476
66591
  var require_guard = __commonJS({
66477
- "../../node_modules/@coderifts/agent-guard/dist/cjs/guard.js"(exports2) {
66592
+ "node_modules/@coderifts/agent-guard/dist/cjs/guard.js"(exports2) {
66478
66593
  "use strict";
66479
66594
  Object.defineProperty(exports2, "__esModule", { value: true });
66480
66595
  exports2.guardToolCall = guardToolCall;
@@ -66494,6 +66609,25 @@ var require_guard = __commonJS({
66494
66609
  }
66495
66610
  }
66496
66611
  }
66612
+ function resolvePreviousReceipt(config) {
66613
+ const pr = config.previousReceipt;
66614
+ if (pr === void 0 || pr === null)
66615
+ return void 0;
66616
+ let raw;
66617
+ if (typeof pr === "function") {
66618
+ try {
66619
+ raw = pr();
66620
+ } catch {
66621
+ return void 0;
66622
+ }
66623
+ } else {
66624
+ raw = pr;
66625
+ }
66626
+ if (typeof raw !== "string")
66627
+ return void 0;
66628
+ const s = raw.trim();
66629
+ return s.length > 0 ? s : void 0;
66630
+ }
66497
66631
  function fingerprint(call) {
66498
66632
  const canon = JSON.stringify({ toolName: call.toolName, arguments: call.arguments, artifacts: call.artifacts, filesTouched: call.filesTouched, diff: call.diff });
66499
66633
  return "sha256:" + (0, node_crypto_1.createHash)("sha256").update(canon).digest("hex");
@@ -66663,7 +66797,7 @@ var require_guard = __commonJS({
66663
66797
  const request = {
66664
66798
  artifacts: detection.artifacts,
66665
66799
  context: { operation: config.operation ?? "tool_call", environment: config.environment, audience: config.audience },
66666
- previous_receipt: void 0,
66800
+ previous_receipt: resolvePreviousReceipt(config),
66667
66801
  idempotency_key: void 0
66668
66802
  };
66669
66803
  const cap = config.maxPayloadBytes ?? 1e6;
@@ -66800,9 +66934,84 @@ var require_guard = __commonJS({
66800
66934
  }
66801
66935
  });
66802
66936
 
66803
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/session-taint.js
66937
+ // node_modules/@coderifts/agent-guard/dist/cjs/receipt-chain.js
66938
+ var require_receipt_chain = __commonJS({
66939
+ "node_modules/@coderifts/agent-guard/dist/cjs/receipt-chain.js"(exports2) {
66940
+ "use strict";
66941
+ Object.defineProperty(exports2, "__esModule", { value: true });
66942
+ exports2.RECEIPT_PREV_NULL = void 0;
66943
+ exports2.previousReceiptCommitment = previousReceiptCommitment;
66944
+ exports2.decodeReceiptBodyPrev = decodeReceiptBodyPrev;
66945
+ exports2.verifyReceiptChainLinkage = verifyReceiptChainLinkage;
66946
+ var node_crypto_1 = require("node:crypto");
66947
+ exports2.RECEIPT_PREV_NULL = "null";
66948
+ function previousReceiptCommitment(previousToken) {
66949
+ return "sha256:" + (0, node_crypto_1.createHash)("sha256").update(previousToken, "utf8").digest("hex");
66950
+ }
66951
+ function decodeReceiptBodyPrev(token) {
66952
+ if (typeof token !== "string" || token.length === 0)
66953
+ return null;
66954
+ const parts = token.split(".");
66955
+ if (parts.length !== 2 || !parts[0] || !parts[1])
66956
+ return null;
66957
+ try {
66958
+ const json = Buffer.from(parts[0], "base64url").toString("utf8");
66959
+ const body = JSON.parse(json);
66960
+ if (typeof body.prev !== "string")
66961
+ return null;
66962
+ return { prev: body.prev };
66963
+ } catch {
66964
+ return null;
66965
+ }
66966
+ }
66967
+ function verifyReceiptChainLinkage(tokens) {
66968
+ const length = tokens.length;
66969
+ if (length === 0) {
66970
+ return { ok: true, length: 0 };
66971
+ }
66972
+ for (let i = 0; i < length; i++) {
66973
+ const decoded = decodeReceiptBodyPrev(tokens[i]);
66974
+ if (!decoded) {
66975
+ return {
66976
+ ok: false,
66977
+ length,
66978
+ failedAt: i,
66979
+ reason: "malformed_token"
66980
+ };
66981
+ }
66982
+ if (i === 0) {
66983
+ if (decoded.prev !== exports2.RECEIPT_PREV_NULL) {
66984
+ return {
66985
+ ok: false,
66986
+ length,
66987
+ failedAt: 0,
66988
+ reason: "unexpected_predecessor",
66989
+ expected: exports2.RECEIPT_PREV_NULL,
66990
+ actual: decoded.prev
66991
+ };
66992
+ }
66993
+ continue;
66994
+ }
66995
+ const expected = previousReceiptCommitment(tokens[i - 1]);
66996
+ if (decoded.prev !== expected) {
66997
+ return {
66998
+ ok: false,
66999
+ length,
67000
+ failedAt: i,
67001
+ reason: "broken_link",
67002
+ expected,
67003
+ actual: decoded.prev
67004
+ };
67005
+ }
67006
+ }
67007
+ return { ok: true, length };
67008
+ }
67009
+ }
67010
+ });
67011
+
67012
+ // node_modules/@coderifts/agent-guard/dist/cjs/session-taint.js
66804
67013
  var require_session_taint = __commonJS({
66805
- "../../node_modules/@coderifts/agent-guard/dist/cjs/session-taint.js"(exports2) {
67014
+ "node_modules/@coderifts/agent-guard/dist/cjs/session-taint.js"(exports2) {
66806
67015
  "use strict";
66807
67016
  Object.defineProperty(exports2, "__esModule", { value: true });
66808
67017
  exports2.SessionTaintTracker = exports2.SESSION_TAINT_VERSION = void 0;
@@ -67107,9 +67316,9 @@ var require_session_taint = __commonJS({
67107
67316
  }
67108
67317
  });
67109
67318
 
67110
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/resolver-yaml.js
67319
+ // node_modules/@coderifts/agent-guard/dist/cjs/resolver-yaml.js
67111
67320
  var require_resolver_yaml = __commonJS({
67112
- "../../node_modules/@coderifts/agent-guard/dist/cjs/resolver-yaml.js"(exports2) {
67321
+ "node_modules/@coderifts/agent-guard/dist/cjs/resolver-yaml.js"(exports2) {
67113
67322
  "use strict";
67114
67323
  Object.defineProperty(exports2, "__esModule", { value: true });
67115
67324
  exports2.YamlLiteError = void 0;
@@ -67328,9 +67537,9 @@ var require_resolver_yaml = __commonJS({
67328
67537
  }
67329
67538
  });
67330
67539
 
67331
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/resolver-glob.js
67540
+ // node_modules/@coderifts/agent-guard/dist/cjs/resolver-glob.js
67332
67541
  var require_resolver_glob = __commonJS({
67333
- "../../node_modules/@coderifts/agent-guard/dist/cjs/resolver-glob.js"(exports2) {
67542
+ "node_modules/@coderifts/agent-guard/dist/cjs/resolver-glob.js"(exports2) {
67334
67543
  "use strict";
67335
67544
  Object.defineProperty(exports2, "__esModule", { value: true });
67336
67545
  exports2.globToRegExp = globToRegExp;
@@ -67383,11 +67592,12 @@ var require_resolver_glob = __commonJS({
67383
67592
  }
67384
67593
  });
67385
67594
 
67386
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/artifact-resolver.js
67595
+ // node_modules/@coderifts/agent-guard/dist/cjs/artifact-resolver.js
67387
67596
  var require_artifact_resolver = __commonJS({
67388
- "../../node_modules/@coderifts/agent-guard/dist/cjs/artifact-resolver.js"(exports2) {
67597
+ "node_modules/@coderifts/agent-guard/dist/cjs/artifact-resolver.js"(exports2) {
67389
67598
  "use strict";
67390
67599
  Object.defineProperty(exports2, "__esModule", { value: true });
67600
+ exports2.classifyByName = classifyByName;
67391
67601
  exports2.resolve = resolve;
67392
67602
  var resolver_yaml_js_1 = require_resolver_yaml();
67393
67603
  var resolver_glob_js_1 = require_resolver_glob();
@@ -67788,14 +67998,15 @@ var require_artifact_resolver = __commonJS({
67788
67998
  }
67789
67999
  });
67790
68000
 
67791
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/tool-registry.js
68001
+ // node_modules/@coderifts/agent-guard/dist/cjs/tool-registry.js
67792
68002
  var require_tool_registry = __commonJS({
67793
- "../../node_modules/@coderifts/agent-guard/dist/cjs/tool-registry.js"(exports2) {
68003
+ "node_modules/@coderifts/agent-guard/dist/cjs/tool-registry.js"(exports2) {
67794
68004
  "use strict";
67795
68005
  Object.defineProperty(exports2, "__esModule", { value: true });
67796
68006
  exports2.RegistryConstructionError = void 0;
67797
68007
  exports2.guardToolRegistry = guardToolRegistry;
67798
68008
  var guard_js_1 = require_guard();
68009
+ var artifact_resolver_js_1 = require_artifact_resolver();
67799
68010
  var RegistryConstructionError = class extends Error {
67800
68011
  code;
67801
68012
  toolName;
@@ -67872,7 +68083,50 @@ var require_tool_registry = __commonJS({
67872
68083
  }
67873
68084
  }
67874
68085
  function defaultBinder(tool, args) {
67875
- return { toolName: tool.name, arguments: args };
68086
+ const d = { toolName: tool.name, arguments: args };
68087
+ if (!args || typeof args !== "object")
68088
+ return d;
68089
+ const a = args;
68090
+ if (Array.isArray(a.artifacts)) {
68091
+ d.artifacts = a.artifacts;
68092
+ return d;
68093
+ }
68094
+ const path = typeof a.path === "string" ? a.path : "";
68095
+ if (!path)
68096
+ return d;
68097
+ const type = (0, artifact_resolver_js_1.classifyByName)(path);
68098
+ if (!type)
68099
+ return d;
68100
+ const bothSides = (oldS, newS) => typeof oldS === "string" && oldS.length > 0 && typeof newS === "string" && newS.length > 0;
68101
+ if (Array.isArray(a.edits)) {
68102
+ const lifted = [];
68103
+ for (let i = 0; i < a.edits.length; i++) {
68104
+ const e = a.edits[i];
68105
+ if (!e || typeof e !== "object")
68106
+ continue;
68107
+ const er = e;
68108
+ if (!bothSides(er.old_string, er.new_string))
68109
+ continue;
68110
+ lifted.push({
68111
+ id: `${type}:${path}#${i}`,
68112
+ type,
68113
+ before: er.old_string,
68114
+ after: er.new_string
68115
+ });
68116
+ }
68117
+ if (lifted.length > 0)
68118
+ d.artifacts = lifted;
68119
+ return d;
68120
+ }
68121
+ if (bothSides(a.old_string, a.new_string)) {
68122
+ d.artifacts = [{
68123
+ id: `${type}:${path}`,
68124
+ type,
68125
+ before: a.old_string,
68126
+ after: a.new_string
68127
+ }];
68128
+ }
68129
+ return d;
67876
68130
  }
67877
68131
  var RAW_EXECUTORS = /* @__PURE__ */ new WeakMap();
67878
68132
  function freezeTool(t) {
@@ -68025,9 +68279,9 @@ var require_tool_registry = __commonJS({
68025
68279
  }
68026
68280
  });
68027
68281
 
68028
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/merge-gate.js
68282
+ // node_modules/@coderifts/agent-guard/dist/cjs/merge-gate.js
68029
68283
  var require_merge_gate = __commonJS({
68030
- "../../node_modules/@coderifts/agent-guard/dist/cjs/merge-gate.js"(exports2) {
68284
+ "node_modules/@coderifts/agent-guard/dist/cjs/merge-gate.js"(exports2) {
68031
68285
  "use strict";
68032
68286
  Object.defineProperty(exports2, "__esModule", { value: true });
68033
68287
  exports2.gateDecision = gateDecision;
@@ -68121,6 +68375,13 @@ var require_merge_gate = __commonJS({
68121
68375
  residual = "protection_advisory_only";
68122
68376
  else
68123
68377
  residual = "protection_not_configured";
68378
+ } else {
68379
+ if (protection.required_check_app_bound === true) {
68380
+ } else if (protection.required_check_app_bound === false) {
68381
+ residual = "required_check_app_not_bound";
68382
+ } else {
68383
+ residual = "required_check_app_binding_unknown";
68384
+ }
68124
68385
  }
68125
68386
  return {
68126
68387
  merge_allowed: true,
@@ -68135,9 +68396,9 @@ var require_merge_gate = __commonJS({
68135
68396
  }
68136
68397
  });
68137
68398
 
68138
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/deploy-gate.js
68399
+ // node_modules/@coderifts/agent-guard/dist/cjs/deploy-gate.js
68139
68400
  var require_deploy_gate = __commonJS({
68140
- "../../node_modules/@coderifts/agent-guard/dist/cjs/deploy-gate.js"(exports2) {
68401
+ "node_modules/@coderifts/agent-guard/dist/cjs/deploy-gate.js"(exports2) {
68141
68402
  "use strict";
68142
68403
  Object.defineProperty(exports2, "__esModule", { value: true });
68143
68404
  exports2.deployGate = deployGate;
@@ -68176,8 +68437,8 @@ var require_deploy_gate = __commonJS({
68176
68437
  const enf = rc.enforcement || { enforcement: "UNKNOWN", bypass_possible: true };
68177
68438
  const enforcement_state = enf.enforcement;
68178
68439
  const opRequired = rc.operation ?? "deploy";
68179
- const requireEnv = rc.require_bound_environment !== false;
68180
- const requireArt = rc.require_bound_artifact !== false;
68440
+ const requireEnv = enforcement_state === "ENFORCING" || rc.require_bound_environment !== false;
68441
+ const requireArt = enforcement_state === "ENFORCING" || rc.require_bound_artifact !== false;
68181
68442
  const allowPending = input.allowPending ?? rc.allowPending ?? false;
68182
68443
  const allowWarnDeploy = input.allowWarnDeploy ?? rc.allowWarnDeploy ?? false;
68183
68444
  const allowPrefix = input.allowPrefixCompare ?? rc.allowPrefixCompare ?? false;
@@ -68260,9 +68521,9 @@ var require_deploy_gate = __commonJS({
68260
68521
  }
68261
68522
  });
68262
68523
 
68263
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/coverage-report.js
68524
+ // node_modules/@coderifts/agent-guard/dist/cjs/coverage-report.js
68264
68525
  var require_coverage_report = __commonJS({
68265
- "../../node_modules/@coderifts/agent-guard/dist/cjs/coverage-report.js"(exports2) {
68526
+ "node_modules/@coderifts/agent-guard/dist/cjs/coverage-report.js"(exports2) {
68266
68527
  "use strict";
68267
68528
  Object.defineProperty(exports2, "__esModule", { value: true });
68268
68529
  exports2.coverageReport = coverageReport;
@@ -68422,12 +68683,133 @@ var require_coverage_report = __commonJS({
68422
68683
  }
68423
68684
  });
68424
68685
 
68425
- // ../../node_modules/@coderifts/agent-guard/dist/cjs/index.js
68686
+ // node_modules/@coderifts/agent-guard/dist/cjs/with-coderifts.js
68687
+ var require_with_coderifts = __commonJS({
68688
+ "node_modules/@coderifts/agent-guard/dist/cjs/with-coderifts.js"(exports2) {
68689
+ "use strict";
68690
+ Object.defineProperty(exports2, "__esModule", { value: true });
68691
+ exports2.withCodeRifts = withCodeRifts;
68692
+ var tool_registry_js_1 = require_tool_registry();
68693
+ var COMPOSITION_CALL_POLICY_COMPLETE = false;
68694
+ var RESIDUAL_CALL_POLICY_INCOMPLETE = "composition_call_policy_incomplete";
68695
+ var RESIDUAL_FORCED_READONLY = "composition_forced_readonly_on_heuristic_mutator";
68696
+ var RESIDUAL_UNKNOWN_READONLY = "composition_unknown_treated_as_readonly";
68697
+ var COVERAGE_STRENGTH = {
68698
+ COMPLETE: 3,
68699
+ PARTIAL: 2,
68700
+ BYPASSED: 1,
68701
+ UNKNOWN: 0
68702
+ };
68703
+ function coverageRank(coverage) {
68704
+ return Object.prototype.hasOwnProperty.call(COVERAGE_STRENGTH, coverage) ? COVERAGE_STRENGTH[coverage] : void 0;
68705
+ }
68706
+ async function safeOnOutcome(onOutcome, payload) {
68707
+ try {
68708
+ await Promise.resolve(onOutcome(payload));
68709
+ } catch {
68710
+ }
68711
+ }
68712
+ function wrapGuardedForObservation(tool, onOutcome) {
68713
+ const innerExecute = tool.execute;
68714
+ const toolName = tool.name;
68715
+ const shell = {
68716
+ name: tool.name,
68717
+ description: tool.description,
68718
+ inputSchema: tool.inputSchema,
68719
+ meta: tool.meta,
68720
+ _coderifts: tool._coderifts,
68721
+ execute: async (args) => {
68722
+ const outcome = await innerExecute(args);
68723
+ await safeOnOutcome(onOutcome, {
68724
+ toolName,
68725
+ // Guarded execute always returns a GuardOutcome from guardToolCall; assert the type for callers.
68726
+ outcome
68727
+ });
68728
+ return outcome;
68729
+ }
68730
+ };
68731
+ if (!Object.isFrozen(shell._coderifts))
68732
+ Object.freeze(shell._coderifts);
68733
+ return Object.freeze(shell);
68734
+ }
68735
+ function withCodeRifts(input) {
68736
+ if (!input || typeof input !== "object") {
68737
+ throw new Error("withCodeRifts: input object is required");
68738
+ }
68739
+ const problems = [];
68740
+ if (typeof input.operation !== "string" || input.operation.trim() === "") {
68741
+ problems.push("`operation` is required and must be a non-empty string (receipts bind to an operation; merge != deploy, so there is no safe default)");
68742
+ }
68743
+ if (input.client == null) {
68744
+ problems.push("`client` is required at construction (guardToolRegistry needs config.guard.client to wrap any mutating tool)");
68745
+ }
68746
+ if (input.requireCoverage !== void 0 && coverageRank(input.requireCoverage) === void 0) {
68747
+ problems.push(`\`requireCoverage\` must be one of COMPLETE | PARTIAL | BYPASSED | UNKNOWN (got ${JSON.stringify(input.requireCoverage)})`);
68748
+ }
68749
+ if (problems.length > 0) {
68750
+ throw new Error(`withCodeRifts: construction aborted \u2014 ${problems.length} condition(s):
68751
+ ` + problems.map((p) => ` - ${p}`).join("\n"));
68752
+ }
68753
+ const reg = input.registry ?? {};
68754
+ const guard = { client: input.client, operation: input.operation };
68755
+ if (input.onEvent !== void 0) {
68756
+ guard.onEvent = input.onEvent;
68757
+ }
68758
+ if (input.previousReceipt !== void 0) {
68759
+ guard.previousReceipt = input.previousReceipt;
68760
+ }
68761
+ const config = {
68762
+ guard,
68763
+ unknownToolPolicy: reg.unknownToolPolicy ?? "mutating",
68764
+ classify: reg.classify,
68765
+ binders: reg.binders,
68766
+ forceReadonly: reg.forceReadonly,
68767
+ failOnUnguardedMutator: reg.failOnUnguardedMutator
68768
+ };
68769
+ const { tools, report } = (0, tool_registry_js_1.guardToolRegistry)(input.tools, config);
68770
+ if (input.requireCoverage !== void 0) {
68771
+ const requiredRank = coverageRank(input.requireCoverage);
68772
+ const actualRank = coverageRank(report.coverage) ?? -1;
68773
+ if (requiredRank !== void 0 && actualRank < requiredRank) {
68774
+ throw new Error(`withCodeRifts: requireCoverage not met \u2014 registry coverage '${report.coverage}' is weaker than required '${input.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.`);
68775
+ }
68776
+ }
68777
+ const compositionInescapableRuntime = report.claim.inescapable_runtime && COMPOSITION_CALL_POLICY_COMPLETE;
68778
+ const residuals = [RESIDUAL_CALL_POLICY_INCOMPLETE];
68779
+ if (report.warnings.some((w) => w.startsWith("force_readonly_on_mutator_heuristic:"))) {
68780
+ residuals.push(RESIDUAL_FORCED_READONLY);
68781
+ }
68782
+ if (report.warnings.includes("unknown_treated_as_readonly")) {
68783
+ residuals.push(RESIDUAL_UNKNOWN_READONLY);
68784
+ }
68785
+ const composition_assurance = {
68786
+ coverage: "PARTIAL",
68787
+ inescapable_runtime: compositionInescapableRuntime,
68788
+ residuals
68789
+ };
68790
+ let toolsOut = tools;
68791
+ if (input.onOutcome) {
68792
+ const onOutcome = input.onOutcome;
68793
+ toolsOut = Object.freeze(tools.map((t) => t._coderifts.guarded ? wrapGuardedForObservation(t, onOutcome) : t));
68794
+ }
68795
+ const result = {
68796
+ tools: toolsOut,
68797
+ registry_report: report,
68798
+ composition_assurance
68799
+ };
68800
+ if (input.repository !== void 0)
68801
+ result.repository = input.repository;
68802
+ return result;
68803
+ }
68804
+ }
68805
+ });
68806
+
68807
+ // node_modules/@coderifts/agent-guard/dist/cjs/index.js
68426
68808
  var require_cjs4 = __commonJS({
68427
- "../../node_modules/@coderifts/agent-guard/dist/cjs/index.js"(exports2) {
68809
+ "node_modules/@coderifts/agent-guard/dist/cjs/index.js"(exports2) {
68428
68810
  "use strict";
68429
68811
  Object.defineProperty(exports2, "__esModule", { value: true });
68430
- exports2.coverageReport = exports2.deployGate = exports2.gateDecision = exports2.RegistryConstructionError = exports2.guardToolRegistry = exports2.globToRegExp = exports2.matchGlob = exports2.resolveArtifacts = exports2.deriveKeySignal = exports2.pathClass = exports2.classifyCommand = exports2.projectState = exports2.emptySessionState = exports2.computeTainted = exports2.evaluate = exports2.updateSession = exports2.SESSION_TAINT_VERSION = exports2.SessionTaintTracker = exports2.readDecision = exports2.computeBundleFingerprint = exports2.computeArtifactDigest = exports2.evaluateEnvelope = exports2.canonicalJson = exports2.computeBodyHash = exports2.bindReceiptToEnvelope = exports2.DETECTOR_VERSION = exports2.builtinDetector = exports2.guardToolCall = void 0;
68812
+ exports2.withCodeRifts = exports2.coverageReport = exports2.deployGate = exports2.gateDecision = exports2.RegistryConstructionError = exports2.guardToolRegistry = exports2.globToRegExp = exports2.matchGlob = exports2.classifyByName = exports2.resolveArtifacts = exports2.deriveKeySignal = exports2.pathClass = exports2.classifyCommand = exports2.projectState = exports2.emptySessionState = exports2.computeTainted = exports2.evaluate = exports2.updateSession = exports2.SESSION_TAINT_VERSION = exports2.SessionTaintTracker = exports2.readDecision = exports2.computeBundleFingerprint = exports2.computeArtifactDigest = exports2.evaluateEnvelope = exports2.RECEIPT_PREV_NULL = exports2.decodeReceiptBodyPrev = exports2.previousReceiptCommitment = exports2.verifyReceiptChainLinkage = exports2.canonicalJson = exports2.computeBodyHash = exports2.bindReceiptToEnvelope = exports2.DETECTOR_VERSION = exports2.builtinDetector = exports2.guardToolCall = void 0;
68431
68813
  var guard_js_1 = require_guard();
68432
68814
  Object.defineProperty(exports2, "guardToolCall", { enumerable: true, get: function() {
68433
68815
  return guard_js_1.guardToolCall;
@@ -68449,6 +68831,19 @@ var require_cjs4 = __commonJS({
68449
68831
  Object.defineProperty(exports2, "canonicalJson", { enumerable: true, get: function() {
68450
68832
  return receipt_binding_js_1.canonicalJson;
68451
68833
  } });
68834
+ var receipt_chain_js_1 = require_receipt_chain();
68835
+ Object.defineProperty(exports2, "verifyReceiptChainLinkage", { enumerable: true, get: function() {
68836
+ return receipt_chain_js_1.verifyReceiptChainLinkage;
68837
+ } });
68838
+ Object.defineProperty(exports2, "previousReceiptCommitment", { enumerable: true, get: function() {
68839
+ return receipt_chain_js_1.previousReceiptCommitment;
68840
+ } });
68841
+ Object.defineProperty(exports2, "decodeReceiptBodyPrev", { enumerable: true, get: function() {
68842
+ return receipt_chain_js_1.decodeReceiptBodyPrev;
68843
+ } });
68844
+ Object.defineProperty(exports2, "RECEIPT_PREV_NULL", { enumerable: true, get: function() {
68845
+ return receipt_chain_js_1.RECEIPT_PREV_NULL;
68846
+ } });
68452
68847
  var enforcement_gate_js_1 = require_enforcement_gate();
68453
68848
  Object.defineProperty(exports2, "evaluateEnvelope", { enumerable: true, get: function() {
68454
68849
  return enforcement_gate_js_1.evaluateEnvelope;
@@ -68498,6 +68893,9 @@ var require_cjs4 = __commonJS({
68498
68893
  Object.defineProperty(exports2, "resolveArtifacts", { enumerable: true, get: function() {
68499
68894
  return artifact_resolver_js_1.resolve;
68500
68895
  } });
68896
+ Object.defineProperty(exports2, "classifyByName", { enumerable: true, get: function() {
68897
+ return artifact_resolver_js_1.classifyByName;
68898
+ } });
68501
68899
  var resolver_glob_js_1 = require_resolver_glob();
68502
68900
  Object.defineProperty(exports2, "matchGlob", { enumerable: true, get: function() {
68503
68901
  return resolver_glob_js_1.matchGlob;
@@ -68524,6 +68922,10 @@ var require_cjs4 = __commonJS({
68524
68922
  Object.defineProperty(exports2, "coverageReport", { enumerable: true, get: function() {
68525
68923
  return coverage_report_js_1.coverageReport;
68526
68924
  } });
68925
+ var with_coderifts_js_1 = require_with_coderifts();
68926
+ Object.defineProperty(exports2, "withCodeRifts", { enumerable: true, get: function() {
68927
+ return with_coderifts_js_1.withCodeRifts;
68928
+ } });
68527
68929
  }
68528
68930
  });
68529
68931
 
@@ -68667,6 +69069,450 @@ var require_deploy_gate2 = __commonJS({
68667
69069
  }
68668
69070
  });
68669
69071
 
69072
+ // src/commands/publish-gate.js
69073
+ var require_publish_gate = __commonJS({
69074
+ "src/commands/publish-gate.js"(exports2, module2) {
69075
+ "use strict";
69076
+ var fs = require("fs");
69077
+ var path = require("path");
69078
+ var { execFileSync } = require("child_process");
69079
+ var chalk = require_source();
69080
+ var { getApiKey } = require_config();
69081
+ var { cloudDiff } = require_cloud();
69082
+ if (process.env.NO_COLOR) chalk.level = 0;
69083
+ var ZERO_SHA = "0000000000000000000000000000000000000000";
69084
+ var CLOSED_ACTIONS = /* @__PURE__ */ new Set([
69085
+ "CONTINUE",
69086
+ "CONTINUE_WITH_MONITORING",
69087
+ "REQUEST_APPROVAL",
69088
+ "STOP"
69089
+ ]);
69090
+ var PERMIT_ACTIONS = /* @__PURE__ */ new Set(["CONTINUE", "CONTINUE_WITH_MONITORING"]);
69091
+ function defaultGit(args, cwd) {
69092
+ return execFileSync("git", args, {
69093
+ cwd: cwd || process.cwd(),
69094
+ encoding: "utf8",
69095
+ maxBuffer: 16 * 1024 * 1024,
69096
+ stdio: ["ignore", "pipe", "pipe"]
69097
+ }).trim();
69098
+ }
69099
+ function gitShow(ref, filePath, { gitImpl = defaultGit, cwd } = {}) {
69100
+ try {
69101
+ const out = gitImpl(["show", `${ref}:${filePath}`], cwd);
69102
+ return { ok: true, content: out == null ? "" : String(out) };
69103
+ } catch (err) {
69104
+ const msg = err && err.stderr ? String(err.stderr) : err && err.message || String(err);
69105
+ return {
69106
+ ok: false,
69107
+ code: "GIT_ERROR",
69108
+ message: `git error reading ${ref}:${filePath}: ${msg.slice(0, 300)}`
69109
+ };
69110
+ }
69111
+ }
69112
+ function readPackageVersion(cwd, readFile = fs.readFileSync) {
69113
+ const pkgPath = path.join(cwd || process.cwd(), "package.json");
69114
+ try {
69115
+ const raw = readFile(pkgPath, "utf8");
69116
+ const pkg2 = JSON.parse(raw);
69117
+ return pkg2 && typeof pkg2.version === "string" ? pkg2.version : null;
69118
+ } catch {
69119
+ return null;
69120
+ }
69121
+ }
69122
+ function resolveBeforeSpec(specPath, {
69123
+ gitImpl = defaultGit,
69124
+ cwd = process.cwd(),
69125
+ readFile = fs.readFileSync,
69126
+ packageVersion = null
69127
+ } = {}) {
69128
+ const version = packageVersion != null ? packageVersion : readPackageVersion(cwd, readFile);
69129
+ const tried = [];
69130
+ if (version) {
69131
+ const tags = [`v${version}`, version];
69132
+ for (const tag of tags) {
69133
+ tried.push(`tag:${tag}`);
69134
+ try {
69135
+ gitImpl(["rev-parse", "--verify", `${tag}^{commit}`], cwd);
69136
+ } catch {
69137
+ continue;
69138
+ }
69139
+ const shown = gitShow(tag, specPath, { gitImpl, cwd });
69140
+ if (!shown.ok) {
69141
+ return {
69142
+ ok: false,
69143
+ code: shown.code || "GIT_ERROR",
69144
+ message: shown.message,
69145
+ tried
69146
+ };
69147
+ }
69148
+ if (shown.content.trim() === "") {
69149
+ return {
69150
+ ok: false,
69151
+ code: "EMPTY_BEFORE",
69152
+ message: `Empty contract artifact at tag ${tag}:${specPath}. Refusing to treat empty before as NEW_ARTIFACT (would false-pass enforce).`,
69153
+ tried
69154
+ };
69155
+ }
69156
+ return { ok: true, content: shown.content, source: `tag:${tag}`, tried };
69157
+ }
69158
+ } else {
69159
+ tried.push("package.json:version (missing)");
69160
+ }
69161
+ const bases = ["origin/main", "origin/master", "main", "master"];
69162
+ for (const base of bases) {
69163
+ tried.push(`merge-base:${base}`);
69164
+ let mb;
69165
+ try {
69166
+ mb = gitImpl(["merge-base", "HEAD", base], cwd);
69167
+ } catch {
69168
+ continue;
69169
+ }
69170
+ if (!mb || mb === ZERO_SHA) continue;
69171
+ const shown = gitShow(mb, specPath, { gitImpl, cwd });
69172
+ if (!shown.ok) {
69173
+ return {
69174
+ ok: false,
69175
+ code: shown.code || "GIT_ERROR",
69176
+ message: shown.message,
69177
+ tried
69178
+ };
69179
+ }
69180
+ if (shown.content.trim() === "") {
69181
+ return {
69182
+ ok: false,
69183
+ code: "EMPTY_BEFORE",
69184
+ message: `Empty contract artifact at merge-base ${mb}:${specPath} (${base}). Refusing to treat empty before as NEW_ARTIFACT (would false-pass enforce).`,
69185
+ tried
69186
+ };
69187
+ }
69188
+ return {
69189
+ ok: true,
69190
+ content: shown.content,
69191
+ source: `merge-base:${base}@${mb.slice(0, 12)}`,
69192
+ tried
69193
+ };
69194
+ }
69195
+ return {
69196
+ ok: false,
69197
+ code: "BEFORE_UNRESOLVED",
69198
+ message: `Could not resolve a non-empty before-spec for ${specPath}. Tried: (a) git tag of package.json version, (b) merge-base with origin/main. Attempts: ${tried.join(", ")}. Fail-closed \u2014 will not publish without a baseline.`,
69199
+ tried
69200
+ };
69201
+ }
69202
+ function resolveAfterSpec(specPath, {
69203
+ cwd = process.cwd(),
69204
+ readFile = fs.readFileSync,
69205
+ exists = fs.existsSync
69206
+ } = {}) {
69207
+ const resolved = path.isAbsolute(specPath) ? specPath : path.join(cwd, specPath);
69208
+ try {
69209
+ if (!exists(resolved)) {
69210
+ return {
69211
+ ok: false,
69212
+ code: "AFTER_MISSING",
69213
+ message: `Working-tree contract artifact not found: ${specPath}`
69214
+ };
69215
+ }
69216
+ const content = readFile(resolved, "utf8");
69217
+ if (content == null || String(content).trim() === "") {
69218
+ return {
69219
+ ok: false,
69220
+ code: "AFTER_EMPTY",
69221
+ message: `Working-tree contract artifact is empty: ${specPath}`
69222
+ };
69223
+ }
69224
+ return { ok: true, content: String(content), path: resolved };
69225
+ } catch (err) {
69226
+ return {
69227
+ ok: false,
69228
+ code: "AFTER_READ_ERROR",
69229
+ message: `Failed to read working-tree ${specPath}: ${err && err.message}`
69230
+ };
69231
+ }
69232
+ }
69233
+ function evaluatePublishPermission(result) {
69234
+ if (!result || typeof result !== "object") {
69235
+ return {
69236
+ allow: false,
69237
+ execution_action: null,
69238
+ decision: null,
69239
+ policy: "fail_closed:unreadable_response"
69240
+ };
69241
+ }
69242
+ const env = result.decision_result && typeof result.decision_result === "object" ? result.decision_result : null;
69243
+ let ea = null;
69244
+ if (env && typeof env.execution_action === "string") ea = env.execution_action;
69245
+ else if (typeof result.execution_action === "string") ea = result.execution_action;
69246
+ const decision = env && env.decision || result.decision || result.omega_decision || null;
69247
+ if (ea && CLOSED_ACTIONS.has(ea)) {
69248
+ const allow = PERMIT_ACTIONS.has(ea);
69249
+ return {
69250
+ allow,
69251
+ execution_action: ea,
69252
+ decision: decision || null,
69253
+ policy: allow ? `permit:execution_action=${ea}` : `block:execution_action=${ea}`
69254
+ };
69255
+ }
69256
+ if (ea != null && ea !== "" && !CLOSED_ACTIONS.has(ea)) {
69257
+ return {
69258
+ allow: false,
69259
+ execution_action: ea,
69260
+ decision: decision || null,
69261
+ policy: `block:unrecognised_execution_action=${ea}`
69262
+ };
69263
+ }
69264
+ if (decision === "BLOCK" || decision === "REQUIRE_APPROVAL") {
69265
+ return {
69266
+ allow: false,
69267
+ execution_action: null,
69268
+ decision,
69269
+ policy: `block:decision=${decision}`
69270
+ };
69271
+ }
69272
+ if (decision === "ALLOW" || decision === "WARN" || decision === "PASS") {
69273
+ return {
69274
+ allow: true,
69275
+ execution_action: null,
69276
+ decision,
69277
+ policy: `permit:decision=${decision}`
69278
+ };
69279
+ }
69280
+ const omega = result.omega_decision;
69281
+ if (omega === "BLOCK" || omega === "REQUIRE_APPROVAL") {
69282
+ return {
69283
+ allow: false,
69284
+ execution_action: null,
69285
+ decision: omega,
69286
+ policy: `block:omega_decision=${omega}`
69287
+ };
69288
+ }
69289
+ return {
69290
+ allow: false,
69291
+ execution_action: ea,
69292
+ decision: decision || omega || null,
69293
+ policy: "fail_closed:no_permission_signal"
69294
+ };
69295
+ }
69296
+ function extractReceiptRef(result) {
69297
+ if (!result || typeof result !== "object") return null;
69298
+ const env = result.decision_result;
69299
+ if (env && env.receipt && typeof env.receipt.token === "string") {
69300
+ return env.receipt.token.slice(0, 24) + (env.receipt.token.length > 24 ? "\u2026" : "");
69301
+ }
69302
+ if (env && typeof env.decision_id === "string") return env.decision_id;
69303
+ if (typeof result.decision_id === "string") return result.decision_id;
69304
+ if (typeof result.fingerprint === "string") return result.fingerprint;
69305
+ if (env && typeof env.fingerprint === "string") return env.fingerprint;
69306
+ return null;
69307
+ }
69308
+ async function defaultPreflight(before, after, { apiKey } = {}) {
69309
+ const key = process.env.CODERIFTS_FORCE_LOCAL_PREFLIGHT ? null : apiKey != null ? apiKey : getApiKey();
69310
+ if (key) {
69311
+ return cloudDiff(before, after, key);
69312
+ }
69313
+ const yaml = require_js_yaml();
69314
+ const { diffSpecs } = require_api2();
69315
+ let oldSpec;
69316
+ let newSpec;
69317
+ try {
69318
+ oldSpec = yaml.load(before);
69319
+ newSpec = yaml.load(after);
69320
+ } catch (e) {
69321
+ const err = new Error(`Failed to parse specs: ${e.message}`);
69322
+ err.code = "PREFLIGHT_UNREACHABLE";
69323
+ throw err;
69324
+ }
69325
+ let diffResult;
69326
+ try {
69327
+ diffResult = await diffSpecs({
69328
+ sourceSpec: { content: JSON.stringify(oldSpec), location: "before.json", format: "openapi3" },
69329
+ destinationSpec: { content: JSON.stringify(newSpec), location: "after.json", format: "openapi3" }
69330
+ });
69331
+ } catch (e) {
69332
+ const err = new Error(`Local preflight engine error: ${e.message}`);
69333
+ err.code = "PREFLIGHT_UNREACHABLE";
69334
+ throw err;
69335
+ }
69336
+ const breaking = (diffResult.breakingDifferences || []).length;
69337
+ const decision = breaking > 0 ? "BLOCK" : "ALLOW";
69338
+ const execution_action = breaking > 0 ? "STOP" : "CONTINUE";
69339
+ return {
69340
+ decision,
69341
+ omega_decision: decision,
69342
+ execution_action,
69343
+ decision_result: {
69344
+ decision,
69345
+ execution_action,
69346
+ decision_id: `local-${Date.now()}`
69347
+ },
69348
+ breaking_changes: diffResult.breakingDifferences || [],
69349
+ risk_score: Math.min(breaking * 15, 100)
69350
+ };
69351
+ }
69352
+ async function runPublishGate(options = {}, deps = {}) {
69353
+ const cwd = deps.cwd || process.cwd();
69354
+ const gitImpl = deps.gitImpl || defaultGit;
69355
+ const readFile = deps.readFile || fs.readFileSync.bind(fs);
69356
+ const exists = deps.exists || fs.existsSync.bind(fs);
69357
+ const preflightFn = deps.preflightFn || defaultPreflight;
69358
+ const log = deps.log || console.log.bind(console);
69359
+ const logErr = deps.logErr || console.error.bind(console);
69360
+ let specPath = options.spec;
69361
+ if (!specPath) {
69362
+ try {
69363
+ specPath = gitImpl(["config", "coderifts.specPath"], cwd);
69364
+ } catch {
69365
+ specPath = "";
69366
+ }
69367
+ }
69368
+ if (!specPath) specPath = "api/openapi.yaml";
69369
+ try {
69370
+ gitImpl(["rev-parse", "--is-inside-work-tree"], cwd);
69371
+ } catch (err) {
69372
+ const msg = "CodeRifts publish-gate: GIT_ERROR \u2014 not a git repository (or git unavailable). Cannot resolve before-spec without git. Fail-closed.";
69373
+ logErr(chalk.red(msg));
69374
+ return finish({
69375
+ ok: false,
69376
+ exitCode: 1,
69377
+ code: "GIT_ERROR",
69378
+ message: msg,
69379
+ policy: "fail_closed:git_error"
69380
+ }, { log, json: options.json });
69381
+ }
69382
+ const beforeRes = resolveBeforeSpec(specPath, {
69383
+ gitImpl,
69384
+ cwd,
69385
+ readFile,
69386
+ packageVersion: deps.packageVersion
69387
+ });
69388
+ if (!beforeRes.ok) {
69389
+ logErr(chalk.red(`CodeRifts publish-gate: ${beforeRes.code} \u2014 ${beforeRes.message}`));
69390
+ return finish({
69391
+ ok: false,
69392
+ exitCode: 1,
69393
+ code: beforeRes.code,
69394
+ message: beforeRes.message,
69395
+ policy: `fail_closed:${beforeRes.code}`,
69396
+ tried: beforeRes.tried
69397
+ }, { log, json: options.json });
69398
+ }
69399
+ const afterRes = resolveAfterSpec(specPath, { cwd, readFile, exists });
69400
+ if (!afterRes.ok) {
69401
+ logErr(chalk.red(`CodeRifts publish-gate: ${afterRes.code} \u2014 ${afterRes.message}`));
69402
+ return finish({
69403
+ ok: false,
69404
+ exitCode: 1,
69405
+ code: afterRes.code,
69406
+ message: afterRes.message,
69407
+ policy: `fail_closed:${afterRes.code}`
69408
+ }, { log, json: options.json });
69409
+ }
69410
+ if (beforeRes.content === afterRes.content) {
69411
+ const payload2 = {
69412
+ ok: true,
69413
+ exitCode: 0,
69414
+ code: "UNCHANGED",
69415
+ message: "Contract artifact unchanged vs baseline; publish permitted.",
69416
+ policy: "permit:unchanged",
69417
+ before_source: beforeRes.source,
69418
+ execution_action: "CONTINUE",
69419
+ receipt: null
69420
+ };
69421
+ if (!options.json) {
69422
+ log(chalk.green("CodeRifts publish-gate: ALLOW (unchanged)"));
69423
+ log(` baseline: ${beforeRes.source}`);
69424
+ log(` spec: ${specPath}`);
69425
+ }
69426
+ return finish(payload2, { log, json: options.json });
69427
+ }
69428
+ let result;
69429
+ try {
69430
+ result = await preflightFn(beforeRes.content, afterRes.content, {
69431
+ apiKey: deps.apiKey,
69432
+ cwd
69433
+ });
69434
+ } catch (err) {
69435
+ const msg = `CodeRifts publish-gate: PREFLIGHT_UNREACHABLE \u2014 ${err && err.message}`;
69436
+ logErr(chalk.red(msg));
69437
+ return finish({
69438
+ ok: false,
69439
+ exitCode: 1,
69440
+ code: "PREFLIGHT_UNREACHABLE",
69441
+ message: msg,
69442
+ policy: "fail_closed:preflight_unreachable"
69443
+ }, { log, json: options.json });
69444
+ }
69445
+ const perm = evaluatePublishPermission(result);
69446
+ const receipt = extractReceiptRef(result);
69447
+ if (!perm.allow) {
69448
+ const payload2 = {
69449
+ ok: false,
69450
+ exitCode: 1,
69451
+ code: "BLOCK",
69452
+ message: "Publish not permitted by execution_action / decision.",
69453
+ policy: perm.policy,
69454
+ execution_action: perm.execution_action,
69455
+ decision: perm.decision,
69456
+ before_source: beforeRes.source,
69457
+ receipt,
69458
+ fail_policy: "exit_1_on_block_or_resolver_error_or_unreachable"
69459
+ };
69460
+ if (!options.json) {
69461
+ logErr("");
69462
+ logErr(chalk.red("========================================"));
69463
+ logErr(chalk.red(" CodeRifts: PUBLISH BLOCKED"));
69464
+ logErr(chalk.red("========================================"));
69465
+ logErr(` Policy: ${perm.policy}`);
69466
+ logErr(` execution_action: ${perm.execution_action || "(none)"}`);
69467
+ logErr(` decision: ${perm.decision || "(none)"}`);
69468
+ logErr(` baseline: ${beforeRes.source}`);
69469
+ logErr(` fail policy: exit 1 on BLOCK / resolver error / preflight unreachability`);
69470
+ logErr(chalk.red("========================================"));
69471
+ logErr("");
69472
+ }
69473
+ return finish(payload2, { log, json: options.json });
69474
+ }
69475
+ const payload = {
69476
+ ok: true,
69477
+ exitCode: 0,
69478
+ code: "ALLOW",
69479
+ message: "Publish permitted.",
69480
+ policy: perm.policy,
69481
+ execution_action: perm.execution_action,
69482
+ decision: perm.decision,
69483
+ before_source: beforeRes.source,
69484
+ receipt
69485
+ };
69486
+ if (!options.json) {
69487
+ log(chalk.green("CodeRifts publish-gate: ALLOW"));
69488
+ log(` Policy: ${perm.policy}`);
69489
+ log(` execution_action: ${perm.execution_action || "(mapped from decision)"}`);
69490
+ log(` baseline: ${beforeRes.source}`);
69491
+ if (receipt) log(` Receipt reference: ${receipt}`);
69492
+ else log(" Receipt reference: (none issued on this path)");
69493
+ }
69494
+ return finish(payload, { log, json: options.json });
69495
+ }
69496
+ function finish(payload, { log, json }) {
69497
+ if (json) {
69498
+ log(JSON.stringify(payload, null, 2));
69499
+ }
69500
+ return payload;
69501
+ }
69502
+ module2.exports = {
69503
+ runPublishGate,
69504
+ resolveBeforeSpec,
69505
+ resolveAfterSpec,
69506
+ evaluatePublishPermission,
69507
+ extractReceiptRef,
69508
+ gitShow,
69509
+ defaultGit,
69510
+ PERMIT_ACTIONS,
69511
+ CLOSED_ACTIONS
69512
+ };
69513
+ }
69514
+ });
69515
+
68670
69516
  // src/commands/init.js
68671
69517
  var require_init = __commonJS({
68672
69518
  "src/commands/init.js"(exports2, module2) {
@@ -94355,6 +95201,8 @@ ${HOOK_MARKER}
94355
95201
  # Checks API spec changes before pushing.
94356
95202
  # The pre-push hook receives lines on stdin:
94357
95203
  # <local ref> <local sha> <remote ref> <remote sha>
95204
+ #
95205
+ # Re-install after CLI upgrades: coderifts hook install
94358
95206
 
94359
95207
  CODERIFTS_API_KEY=$(git config coderifts.apiKey)
94360
95208
  SPEC_PATH=$(git config coderifts.specPath || echo "api/openapi.yaml")
@@ -94365,6 +95213,53 @@ if [ -z "$CODERIFTS_API_KEY" ]; then
94365
95213
  exit 0 # Don't block if not configured
94366
95214
  fi
94367
95215
 
95216
+ # --- helpers: three-state git blob read (present | absent | error) ---
95217
+ # Sets: BLOB_KIND, BLOB_CONTENT, BLOB_ERR. Never maps unreadable \u2192 empty string.
95218
+ git_blob_at() {
95219
+ _ref="$1"
95220
+ _path="$2"
95221
+ BLOB_CONTENT=""
95222
+ BLOB_ERR=""
95223
+ BLOB_KIND=""
95224
+ if ! git rev-parse --verify "$_ref^{commit}" >/dev/null 2>&1; then
95225
+ BLOB_KIND=error
95226
+ BLOB_ERR="GIT_ERROR: cannot resolve ref $_ref"
95227
+ return 1
95228
+ fi
95229
+ _errf=$(mktemp 2>/dev/null || echo "/tmp/coderifts-hook-err.$$")
95230
+ if BLOB_CONTENT=$(git show "$_ref:$_path" 2>"$_errf"); then
95231
+ BLOB_KIND=present
95232
+ rm -f "$_errf"
95233
+ return 0
95234
+ fi
95235
+ _err=$(cat "$_errf" 2>/dev/null)
95236
+ rm -f "$_errf"
95237
+ case "$_err" in
95238
+ *"does not exist in"*|*"exists on disk, but not in"*)
95239
+ BLOB_KIND=absent
95240
+ BLOB_CONTENT=""
95241
+ return 0
95242
+ ;;
95243
+ esac
95244
+ BLOB_KIND=error
95245
+ BLOB_ERR="GIT_ERROR: git show $_ref:$_path failed"
95246
+ return 1
95247
+ }
95248
+
95249
+ # New-branch baseline: merge-base with default branch (not empty before).
95250
+ # Prints merge-base SHA on success; nonzero if none can be resolved.
95251
+ resolve_new_branch_base_ref() {
95252
+ _local="$1"
95253
+ for _cand in origin/HEAD origin/main origin/master main master; do
95254
+ _mb=$(git merge-base "$_local" "$_cand" 2>/dev/null) || continue
95255
+ if [ -n "$_mb" ] && [ "$_mb" != "$ZERO" ]; then
95256
+ echo "$_mb"
95257
+ return 0
95258
+ fi
95259
+ done
95260
+ return 1
95261
+ }
95262
+
94368
95263
  # Read stdin lines provided by git pre-push
94369
95264
  while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do
94370
95265
  # Skip delete pushes
@@ -94372,41 +95267,93 @@ while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do
94372
95267
  continue
94373
95268
  fi
94374
95269
 
94375
- # Get the spec at the local (about-to-be-pushed) commit
94376
- HEAD_SPEC=$(git show "$LOCAL_SHA:$SPEC_PATH" 2>/dev/null)
94377
- if [ -z "$HEAD_SPEC" ]; then
95270
+ # after = local (about-to-be-pushed) commit \u2014 three-state
95271
+ if ! git_blob_at "$LOCAL_SHA" "$SPEC_PATH"; then
95272
+ echo "CodeRifts: $BLOB_ERR (after=$SPEC_PATH at $LOCAL_SHA). Fail-closed."
95273
+ exit 1
95274
+ fi
95275
+ if [ "$BLOB_KIND" = "absent" ]; then
94378
95276
  continue # Spec doesn't exist in local commit, skip
94379
95277
  fi
95278
+ HEAD_SPEC=$BLOB_CONTENT
94380
95279
 
94381
- # Get the spec at the remote (already-pushed) commit
95280
+ # before = remote tip, or for new branch (zero remote SHA) a merge-base baseline
94382
95281
  if [ "$REMOTE_SHA" = "$ZERO" ]; then
94383
- # New branch \u2014 no remote baseline, use empty spec
94384
- BASE_SPEC=""
95282
+ BASE_REF=$(resolve_new_branch_base_ref "$LOCAL_SHA") || {
95283
+ echo "CodeRifts: GIT_ERROR \u2014 cannot resolve merge-base baseline for new branch (tried origin/HEAD, origin/main, origin/master, main, master). Fail-closed."
95284
+ exit 1
95285
+ }
94385
95286
  else
94386
- BASE_SPEC=$(git show "$REMOTE_SHA:$SPEC_PATH" 2>/dev/null || echo "")
95287
+ BASE_REF=$REMOTE_SHA
94387
95288
  fi
94388
95289
 
94389
- # If base is empty (new spec or new branch), allow
94390
- if [ -z "$BASE_SPEC" ]; then
94391
- echo "CodeRifts: New spec detected, allowing push."
95290
+ if ! git_blob_at "$BASE_REF" "$SPEC_PATH"; then
95291
+ echo "CodeRifts: $BLOB_ERR (before=$SPEC_PATH at $BASE_REF). Fail-closed \u2014 not treating as new spec."
95292
+ exit 1
95293
+ fi
95294
+ if [ "$BLOB_KIND" = "absent" ]; then
95295
+ # Honest NEW_ARTIFACT: path genuinely not at baseline
95296
+ echo "CodeRifts: New artifact (spec absent at baseline $BASE_REF:$SPEC_PATH); allowing push."
94392
95297
  continue
94393
95298
  fi
95299
+ BASE_SPEC=$BLOB_CONTENT
94394
95300
 
94395
95301
  # If specs are identical, nothing to check
94396
95302
  if [ "$BASE_SPEC" = "$HEAD_SPEC" ]; then
94397
95303
  continue
94398
95304
  fi
94399
95305
 
94400
- echo "CodeRifts: Checking API spec changes..."
95306
+ echo "CodeRifts: Checking API spec changes (baseline $BASE_REF)..."
94401
95307
 
94402
95308
  RESULT=$(curl -s -X POST https://app.coderifts.com/api/v1/diff \\
94403
95309
  -H "Authorization: Bearer $CODERIFTS_API_KEY" \\
94404
95310
  -H "Content-Type: application/json" \\
94405
95311
  -d "{\\"before\\": $(echo "$BASE_SPEC" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))'), \\"after\\": $(echo "$HEAD_SPEC" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))')}")
94406
95312
 
94407
- DECISION=$(echo $RESULT | python3 -c "import sys,json; print(json.load(sys.stdin).get('omega_decision','ALLOW'))" 2>/dev/null)
94408
- OMEGA=$(echo $RESULT | python3 -c "import sys,json; print(json.load(sys.stdin).get('omega_api',0))" 2>/dev/null)
94409
- BREAKING=$(echo $RESULT | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('breaking_changes',[])))" 2>/dev/null)
95313
+ # Prefer closed-set execution_action; omega_decision only when action is absent.
95314
+ # Severity (unchanged): BLOCK/STOP \u2192 exit 1; REQUIRE_APPROVAL/WARN \u2192 warn; unknown action \u2192 halt.
95315
+ DECISION=$(echo "$RESULT" | python3 -c '
95316
+ import sys, json
95317
+ try:
95318
+ d = json.load(sys.stdin)
95319
+ except Exception:
95320
+ print("ALLOW")
95321
+ raise SystemExit(0)
95322
+ ea = None
95323
+ dr = d.get("decision_result")
95324
+ if isinstance(dr, dict) and isinstance(dr.get("execution_action"), str):
95325
+ ea = dr["execution_action"]
95326
+ elif isinstance(d.get("execution_action"), str):
95327
+ ea = d["execution_action"]
95328
+ closed = {"CONTINUE", "CONTINUE_WITH_MONITORING", "REQUEST_APPROVAL", "STOP"}
95329
+ if ea is not None and ea != "":
95330
+ if ea not in closed:
95331
+ print("UNKNOWN")
95332
+ raise SystemExit(0)
95333
+ if ea in ("CONTINUE", "CONTINUE_WITH_MONITORING"):
95334
+ print("ALLOW")
95335
+ elif ea == "STOP":
95336
+ print("BLOCK")
95337
+ else:
95338
+ print("REQUIRE_APPROVAL")
95339
+ raise SystemExit(0)
95340
+ od = d.get("omega_decision") or d.get("decision") or "ALLOW"
95341
+ print(od)
95342
+ ' 2>/dev/null)
95343
+ OMEGA=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('omega_api',0))" 2>/dev/null)
95344
+ BREAKING=$(echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('breaking_changes',[])))" 2>/dev/null)
95345
+
95346
+ if [ "$DECISION" = "UNKNOWN" ]; then
95347
+ echo ""
95348
+ echo "========================================"
95349
+ echo " CodeRifts: PUSH BLOCKED"
95350
+ echo "========================================"
95351
+ echo " Reason: unrecognised execution_action is not permission"
95352
+ echo " Fail-closed (unknown present action)."
95353
+ echo "========================================"
95354
+ echo ""
95355
+ exit 1
95356
+ fi
94410
95357
 
94411
95358
  if [ "$DECISION" = "BLOCK" ]; then
94412
95359
  echo ""
@@ -94474,6 +95421,10 @@ exit 0
94474
95421
  console.log("");
94475
95422
  console.log("Optionally set spec path (default: api/openapi.yaml):");
94476
95423
  console.log(" git config coderifts.specPath path/to/openapi.yaml");
95424
+ console.log("");
95425
+ console.log("After upgrading the coderifts CLI, re-run this command so the installed");
95426
+ console.log("hook matches the package (already-installed hooks are not auto-updated):");
95427
+ console.log(" coderifts hook install");
94477
95428
  }
94478
95429
  function uninstall() {
94479
95430
  const gitDir = findGitDir();
@@ -95843,6 +96794,7 @@ var require_mcp_poisoning_detector = __commonJS({
95843
96794
  "../../src/mcp-poisoning-detector.js"(exports2, module2) {
95844
96795
  "use strict";
95845
96796
  var SENSITIVE_OBJECT = "(secrets?|credentials?|tokens?|passwords?|api[\\s_-]?keys?|private[\\s_-]?keys?|env|environment|conversation|chat\\s*history|context|user\\s*data|session)";
96797
+ var SENSITIVE_SCOPE = "(any|all|every|stored|user\\'?s?|the\\s+user\\'?s?|all\\s+environment)";
95846
96798
  var SUSPICIOUS_PATTERNS = [
95847
96799
  // Injection / "ignore your instructions" family. The trailing object
95848
96800
  // (instructions|rules|prompts|context) is OPTIONAL so "ignore previous and ..."
@@ -95855,6 +96807,21 @@ var require_mcp_poisoning_detector = __commonJS({
95855
96807
  /exfiltrate|steal|leak|send\s+to\s+external/i,
95856
96808
  // Exfiltration-intent family: an action verb targeting a sensitive payload.
95857
96809
  /\b(send|forward|copy|upload|post|transmit|exfiltrate|leak)\b[\s\S]{0,40}?\b(conversation|chat|history|context|messages?|credentials?|secrets?|tokens?|api\s*keys?|keys?|passwords?|data)\b/i,
96810
+ // Return/echo scoped sensitive material without a path ("return any stored credentials").
96811
+ // Scope word required — bare "return the new API token" must stay quiet.
96812
+ new RegExp(
96813
+ "\\b(return|echo|reveal|expose|send)\\b[\\s\\S]{0,30}?\\b" + SENSITIVE_SCOPE + "\\s+(secrets?|credentials?|tokens?|passwords?|private[\\s_-]?keys?|environment\\s+variables?|env)\\b",
96814
+ "i"
96815
+ ),
96816
+ // Retrieve private-key material + echo/return (intent without a filesystem path).
96817
+ // Narrow: requires both a retrieve-class verb and an echo/return/reveal verb around key material.
96818
+ /\b(retrieve|fetch|extract|obtain|collect)\b[\s\S]{0,60}?\b(private[\s_-]?keys?(?:\s+material)?|secret[\s_-]?keys?|key\s+material)\b[\s\S]{0,50}?\b(echo|return|send|reveal|expose)\b/i,
96819
+ // Outbound destination without a named secret: exfil-shaped phrasing + http(s) URL.
96820
+ // Bare URL alone stays quiet (legit tools reference docs / configured webhook URLs).
96821
+ // "Sends the result to https://hooks…" (tool purpose) must NOT fire — requires "a copy"
96822
+ // or "also send" as the exfil marker, not mere "send … to <url>".
96823
+ /\b(send|forward|post|upload|transmit)\s+a\s+copy\b[\s\S]{0,50}?https?:\/\//i,
96824
+ /\balso\s+send\b[\s\S]{0,60}?https?:\/\//i,
95858
96825
  /execute\s+(shell|command|code|system)/i,
95859
96826
  /bypass\s+(auth|security|validation|filter)/i,
95860
96827
  /override\s+(safety|policy|rules?)/i,
@@ -95866,8 +96833,8 @@ var require_mcp_poisoning_detector = __commonJS({
95866
96833
  /return\s+secret|exfiltrat|leak\s+data/i
95867
96834
  ];
95868
96835
  var URL_PATTERN = /https?:\/\/[^\s)'"]+/i;
95869
- var SENSITIVE_PATH_PATTERN = /(~\/\.ssh|~\/\.cursor|~\/\.aws|\.aws\/|\.env\b|\/etc\/|mcp\.json|credentials|id_rsa|\.ssh\/|private[\s_-]?keys?)/i;
95870
- var CONTENT_MOVE_VERB_PATTERN = /\b(pass|send|return|forward|include|read|upload|post|transmit|copy|exfiltrate|leak)\b/i;
96836
+ var SENSITIVE_PATH_PATTERN = /(~\/\.ssh|~\/\.cursor|~\/\.aws|\.aws\/|\.env\b|\/etc\/|mcp\.json|id_rsa|\.ssh\/|\/credentials(?:\.|\/)|credentials\.(?:json|txt|pem|env)|\.credentials\b)/i;
96837
+ var CONTENT_MOVE_VERB_PATTERN = /\b(pass|send|return|forward|include|read|upload|post|transmit|copy|exfiltrate|leak|echo|reveal|expose)\b/i;
95871
96838
  var BASE64_BLOB_PATTERN = /[A-Za-z0-9+/]{40,}={0,2}/;
95872
96839
  function isLikelyBase64(s) {
95873
96840
  if (/=$/.test(s)) return true;
@@ -96406,6 +97373,13 @@ program.command("deploy-gate").description("Gate a deploy on the current { envir
96406
97373
  const { runDeployGate } = require_deploy_gate2();
96407
97374
  await runDeployGate(options);
96408
97375
  });
97376
+ program.command("publish-gate").description("Gate npm publish on contract-artifact preflight (before=git baseline, after=working tree)").option("--spec <path>", "Contract artifact path (default: git config coderifts.specPath or api/openapi.yaml)").option("--json", "Machine-readable JSON result").action(async (options) => {
97377
+ const { runPublishGate } = require_publish_gate();
97378
+ const result = await runPublishGate(options);
97379
+ const code = result && typeof result.exitCode === "number" ? result.exitCode : 1;
97380
+ process.exitCode = code;
97381
+ process.exit(code);
97382
+ });
96409
97383
  program.command("init [template]").description("Generate a .coderifts.yml from a policy template (startup, growth, fintech, public-api, microservices)").action(async (template) => {
96410
97384
  const { init } = require_init();
96411
97385
  await init(template);
@@ -96432,7 +97406,11 @@ corpusCmd.command("verify", { isDefault: true }).description("Evaluate every tru
96432
97406
  const { corpusVerify } = require_corpus();
96433
97407
  corpusVerify(options);
96434
97408
  });
96435
- program.parse();
97409
+ program.parseAsync(process.argv).catch((err) => {
97410
+ console.error(err);
97411
+ process.exitCode = typeof process.exitCode === "number" && process.exitCode !== 0 ? process.exitCode : 1;
97412
+ process.exit(process.exitCode);
97413
+ });
96436
97414
  /*! Bundled license information:
96437
97415
 
96438
97416
  safe-buffer/index.js: