coderifts 1.8.4 → 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.8.4",
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",
@@ -3050,11 +3050,12 @@ var require_package = __commonJS({
3050
3050
  test: "node --test test/*.test.js"
3051
3051
  },
3052
3052
  dependencies: {
3053
+ "@coderifts/agent-guard": "^1.6.0",
3053
3054
  chalk: "^4.1.2",
3054
3055
  "cli-table3": "^0.6.4",
3055
3056
  commander: "^12.0.0",
3056
3057
  inquirer: "^8.2.6",
3057
- "js-yaml": "^4.2.0",
3058
+ "js-yaml": "^4.3.1",
3058
3059
  "openapi-diff": "^0.24.1",
3059
3060
  ora: "^5.4.1"
3060
3061
  },
@@ -3062,7 +3063,9 @@ var require_package = __commonJS({
3062
3063
  "z-schema": "^7.2.0",
3063
3064
  "json-schema-ref-parser": "npm:@apidevtools/json-schema-ref-parser@^11.7.3",
3064
3065
  "form-data": "^4.0.6",
3065
- axios: ">=1.18.0"
3066
+ axios: ">=1.18.0",
3067
+ "fast-uri": ">=3.1.5",
3068
+ "brace-expansion": "5.0.9"
3066
3069
  },
3067
3070
  devDependencies: {
3068
3071
  esbuild: "^0.28.1"
@@ -4366,7 +4369,7 @@ var require_templates = __commonJS({
4366
4369
  if (!Number.isNaN(number)) {
4367
4370
  results.push(number);
4368
4371
  } else if (matches = chunk.match(STRING_REGEX)) {
4369
- 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));
4370
4373
  } else {
4371
4374
  throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
4372
4375
  }
@@ -11255,7 +11258,7 @@ var require_omap = __commonJS({
11255
11258
  var _toString = Object.prototype.toString;
11256
11259
  function resolveYamlOmap(data) {
11257
11260
  if (data === null) return true;
11258
- const objectKeys = [];
11261
+ const objectKeys = {};
11259
11262
  const object = data;
11260
11263
  for (let index = 0, length = object.length; index < length; index += 1) {
11261
11264
  const pair = object[index];
@@ -11269,8 +11272,8 @@ var require_omap = __commonJS({
11269
11272
  }
11270
11273
  }
11271
11274
  if (!pairHasKey) return false;
11272
- if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
11273
- else return false;
11275
+ if (_hasOwnProperty.call(objectKeys, pairKey)) return false;
11276
+ Object.defineProperty(objectKeys, pairKey, { value: true });
11274
11277
  }
11275
11278
  return true;
11276
11279
  }
@@ -24777,7 +24780,7 @@ var require_lodash = __commonJS({
24777
24780
  position -= target.length;
24778
24781
  return position >= 0 && string.slice(position, end) == target;
24779
24782
  }
24780
- function escape2(string) {
24783
+ function escape(string) {
24781
24784
  string = toString(string);
24782
24785
  return string && reHasUnescapedHtml.test(string) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string;
24783
24786
  }
@@ -25388,7 +25391,7 @@ var require_lodash = __commonJS({
25388
25391
  lodash.divide = divide;
25389
25392
  lodash.endsWith = endsWith;
25390
25393
  lodash.eq = eq;
25391
- lodash.escape = escape2;
25394
+ lodash.escape = escape;
25392
25395
  lodash.escapeRegExp = escapeRegExp;
25393
25396
  lodash.every = every;
25394
25397
  lodash.find = find;
@@ -29362,6 +29365,7 @@ var require_utils2 = __commonJS({
29362
29365
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
29363
29366
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
29364
29367
  var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
29368
+ var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/?]$/iu);
29365
29369
  function stringArrayToHexStripped(input) {
29366
29370
  let acc = "";
29367
29371
  let code = 0;
@@ -29504,7 +29508,7 @@ var require_utils2 = __commonJS({
29504
29508
  continue;
29505
29509
  }
29506
29510
  } else if (input[0] === "/") {
29507
- if (input[1] === "." || input[1] === "/") {
29511
+ if (input[1] === ".") {
29508
29512
  output.push("/");
29509
29513
  break;
29510
29514
  }
@@ -29586,10 +29590,30 @@ var require_utils2 = __commonJS({
29586
29590
  }
29587
29591
  return output;
29588
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
+ }
29589
29612
  function normalizePathEncoding(input) {
29590
29613
  let output = "";
29591
29614
  for (let i = 0; i < input.length; i++) {
29592
- if (input[i] === "%" && i + 2 < input.length) {
29615
+ const ch = input[i];
29616
+ if (ch === "%" && i + 2 < input.length) {
29593
29617
  const hex = input.slice(i + 1, i + 3);
29594
29618
  if (isHexPair(hex)) {
29595
29619
  const normalizedHex = hex.toUpperCase();
@@ -29603,10 +29627,66 @@ var require_utils2 = __commonJS({
29603
29627
  continue;
29604
29628
  }
29605
29629
  }
29606
- if (isPathCharacter(input[i])) {
29607
- output += input[i];
29630
+ if (isPathCharacter(ch)) {
29631
+ output += ch;
29608
29632
  } else {
29609
- output += escape(input[i]);
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;
29673
+ } else {
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
+ }
29610
29690
  }
29611
29691
  }
29612
29692
  return output;
@@ -29614,7 +29694,8 @@ var require_utils2 = __commonJS({
29614
29694
  function escapePreservingEscapes(input) {
29615
29695
  let output = "";
29616
29696
  for (let i = 0; i < input.length; i++) {
29617
- if (input[i] === "%" && i + 2 < input.length) {
29697
+ const ch = input[i];
29698
+ if (ch === "%" && i + 2 < input.length) {
29618
29699
  const hex = input.slice(i + 1, i + 3);
29619
29700
  if (isHexPair(hex)) {
29620
29701
  output += "%" + hex.toUpperCase();
@@ -29622,7 +29703,22 @@ var require_utils2 = __commonJS({
29622
29703
  continue;
29623
29704
  }
29624
29705
  }
29625
- 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
+ }
29626
29722
  }
29627
29723
  return output;
29628
29724
  }
@@ -29656,6 +29752,7 @@ var require_utils2 = __commonJS({
29656
29752
  reescapeHostDelimiters,
29657
29753
  normalizePercentEncoding,
29658
29754
  normalizePathEncoding,
29755
+ normalizeQueryFragmentEncoding,
29659
29756
  escapePreservingEscapes,
29660
29757
  removeDotSegments,
29661
29758
  isIPv4,
@@ -29880,7 +29977,7 @@ var require_schemes = __commonJS({
29880
29977
  var require_fast_uri = __commonJS({
29881
29978
  "node_modules/fast-uri/index.js"(exports2, module2) {
29882
29979
  "use strict";
29883
- 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();
29884
29981
  var { SCHEMES, getSchemeHandler } = require_schemes();
29885
29982
  function normalize(uri, options) {
29886
29983
  if (typeof uri === "string") {
@@ -29894,7 +29991,12 @@ var require_fast_uri = __commonJS({
29894
29991
  }
29895
29992
  function resolve(baseURI, relativeURI, options) {
29896
29993
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
29897
- 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);
29898
30000
  schemelessOptions.skipEscape = true;
29899
30001
  return serialize(resolved, schemelessOptions);
29900
30002
  }
@@ -30020,6 +30122,7 @@ var require_fast_uri = __commonJS({
30020
30122
  }
30021
30123
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
30022
30124
  var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
30125
+ var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
30023
30126
  function getParseError(parsed, matches) {
30024
30127
  if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
30025
30128
  return 'URI path must start with "/" when authority is present.';
@@ -30054,9 +30157,23 @@ var require_fast_uri = __commonJS({
30054
30157
  parsed.error = "URI authority must not contain a literal backslash.";
30055
30158
  malformedAuthorityOrPort = true;
30056
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
+ }
30057
30174
  const matches = uri.match(URI_PARSE);
30058
30175
  if (matches) {
30059
- parsed.scheme = matches[1];
30176
+ parsed.scheme = matches[1] === void 0 ? void 0 : matches[1].toLowerCase();
30060
30177
  parsed.userinfo = matches[3];
30061
30178
  parsed.host = matches[4];
30062
30179
  parsed.port = parseInt(matches[5], 10);
@@ -30115,12 +30232,11 @@ var require_fast_uri = __commonJS({
30115
30232
  if (parsed.path) {
30116
30233
  parsed.path = normalizePathEncoding(parsed.path);
30117
30234
  }
30235
+ if (parsed.query) {
30236
+ parsed.query = normalizeQueryFragmentEncoding(parsed.query);
30237
+ }
30118
30238
  if (parsed.fragment) {
30119
- try {
30120
- parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
30121
- } catch {
30122
- parsed.error = parsed.error || "URI malformed";
30123
- }
30239
+ parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
30124
30240
  }
30125
30241
  }
30126
30242
  if (schemeHandler && schemeHandler.parse) {
@@ -61749,7 +61865,7 @@ var require_axios = __commonJS({
61749
61865
  advertiseZstdAcceptEncoding: false,
61750
61866
  validateStatusUndefinedResolves: true
61751
61867
  };
61752
- var URLSearchParams = url.URLSearchParams;
61868
+ var URLSearchParams2 = url.URLSearchParams;
61753
61869
  var ALPHA = "abcdefghijklmnopqrstuvwxyz";
61754
61870
  var DIGIT = "0123456789";
61755
61871
  var ALPHABET = {
@@ -61772,7 +61888,7 @@ var require_axios = __commonJS({
61772
61888
  var platform$1 = {
61773
61889
  isNode: true,
61774
61890
  classes: {
61775
- URLSearchParams,
61891
+ URLSearchParams: URLSearchParams2,
61776
61892
  FormData: FormData$1,
61777
61893
  Blob: typeof Blob !== "undefined" && Blob || null
61778
61894
  },
@@ -65405,6 +65521,3998 @@ var require_diff = __commonJS({
65405
65521
  }
65406
65522
  });
65407
65523
 
65524
+ // node_modules/@coderifts/sdk/dist/cjs/errors.js
65525
+ var require_errors5 = __commonJS({
65526
+ "node_modules/@coderifts/sdk/dist/cjs/errors.js"(exports2) {
65527
+ "use strict";
65528
+ Object.defineProperty(exports2, "__esModule", { value: true });
65529
+ exports2.AuthError = exports2.RateLimitError = exports2.TimeoutError = exports2.ApiError = exports2.CodeRiftsError = void 0;
65530
+ var CodeRiftsError = class extends Error {
65531
+ code;
65532
+ constructor(message, code = "unknown") {
65533
+ super(message);
65534
+ this.name = "CodeRiftsError";
65535
+ this.code = code;
65536
+ }
65537
+ };
65538
+ exports2.CodeRiftsError = CodeRiftsError;
65539
+ var ApiError = class extends CodeRiftsError {
65540
+ status;
65541
+ code;
65542
+ body;
65543
+ constructor(status, body) {
65544
+ super(`[${status}] ${body.error}: ${body.message}`);
65545
+ this.name = "ApiError";
65546
+ this.status = status;
65547
+ this.code = body.error;
65548
+ this.body = body;
65549
+ }
65550
+ };
65551
+ exports2.ApiError = ApiError;
65552
+ var TimeoutError = class extends CodeRiftsError {
65553
+ constructor(timeoutMs) {
65554
+ super(`Request timed out after ${timeoutMs}ms`);
65555
+ this.name = "TimeoutError";
65556
+ }
65557
+ };
65558
+ exports2.TimeoutError = TimeoutError;
65559
+ var RateLimitError = class extends ApiError {
65560
+ constructor(body) {
65561
+ super(429, body);
65562
+ this.name = "RateLimitError";
65563
+ }
65564
+ };
65565
+ exports2.RateLimitError = RateLimitError;
65566
+ var AuthError = class extends ApiError {
65567
+ constructor(body) {
65568
+ super(401, body);
65569
+ this.name = "AuthError";
65570
+ }
65571
+ };
65572
+ exports2.AuthError = AuthError;
65573
+ }
65574
+ });
65575
+
65576
+ // node_modules/@coderifts/sdk/dist/cjs/client.js
65577
+ var require_client = __commonJS({
65578
+ "node_modules/@coderifts/sdk/dist/cjs/client.js"(exports2) {
65579
+ "use strict";
65580
+ Object.defineProperty(exports2, "__esModule", { value: true });
65581
+ exports2.CodeRifts = void 0;
65582
+ var errors_js_1 = require_errors5();
65583
+ var DEFAULT_BASE_URL = "https://app.coderifts.com";
65584
+ var DEFAULT_TIMEOUT = 3e4;
65585
+ var CodeRifts = class {
65586
+ apiKey;
65587
+ baseUrl;
65588
+ timeout;
65589
+ constructor(options) {
65590
+ if (!options.apiKey) {
65591
+ throw new Error("apiKey is required");
65592
+ }
65593
+ this.apiKey = options.apiKey;
65594
+ this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
65595
+ this.timeout = options.timeout || DEFAULT_TIMEOUT;
65596
+ }
65597
+ // ─── Internal HTTP helper ──────────────────────────────────────────────
65598
+ async request(method, path, body) {
65599
+ const url = `${this.baseUrl}${path}`;
65600
+ const controller = new AbortController();
65601
+ const timer = setTimeout(() => controller.abort(), this.timeout);
65602
+ try {
65603
+ const res = await fetch(url, {
65604
+ method,
65605
+ headers: {
65606
+ "Content-Type": "application/json",
65607
+ Authorization: `Bearer ${this.apiKey}`
65608
+ },
65609
+ body: body ? JSON.stringify(body) : void 0,
65610
+ signal: controller.signal
65611
+ });
65612
+ const json = await res.json();
65613
+ if (!res.ok) {
65614
+ const errorBody = {
65615
+ error: json.error || "unknown",
65616
+ message: json.message || res.statusText
65617
+ };
65618
+ if (res.status === 401)
65619
+ throw new errors_js_1.AuthError(errorBody);
65620
+ if (res.status === 429)
65621
+ throw new errors_js_1.RateLimitError(errorBody);
65622
+ throw new errors_js_1.ApiError(res.status, errorBody);
65623
+ }
65624
+ return json;
65625
+ } catch (err) {
65626
+ if (err instanceof errors_js_1.ApiError)
65627
+ throw err;
65628
+ if (err.name === "AbortError") {
65629
+ throw new errors_js_1.TimeoutError(this.timeout);
65630
+ }
65631
+ throw err;
65632
+ } finally {
65633
+ clearTimeout(timer);
65634
+ }
65635
+ }
65636
+ // ─── 1. preflightCheck ─────────────────────────────────────────────────
65637
+ /**
65638
+ * Check whether it is safe to proceed with a tool invocation.
65639
+ *
65640
+ * Accepts `old_spec` / `new_spec` (OpenAPI YAML strings) and a `tool_name`.
65641
+ * The SDK converts the specs to MCP tool arrays and calls POST /api/v1/agent/preflight.
65642
+ */
65643
+ async preflightCheck(req) {
65644
+ const raw = await this.request("POST", "/api/v1/agent/preflight", {
65645
+ tool_name: req.tool_name,
65646
+ old_spec: req.old_spec,
65647
+ new_spec: req.new_spec
65648
+ });
65649
+ const decision = raw.decision || "ALLOW";
65650
+ return {
65651
+ decision,
65652
+ omega_api: raw.omega_api ?? 0,
65653
+ safe: decision === "ALLOW" || decision === "WARN",
65654
+ reflex_triggers: raw.reflex_triggers || [],
65655
+ affected_tools: raw.affected_tools || [],
65656
+ confidence_score: raw.confidence_score,
65657
+ reflex_override: raw.reflex_override,
65658
+ omega_components: raw.omega_components,
65659
+ breaking_changes: raw.breaking_changes,
65660
+ stats: raw.stats,
65661
+ mitigation_available: raw.mitigation_available
65662
+ };
65663
+ }
65664
+ // ─── 2. diff ───────────────────────────────────────────────────────────
65665
+ /**
65666
+ * Full analysis of two OpenAPI specs.
65667
+ */
65668
+ async diff(req) {
65669
+ return this.request("POST", "/api/v1/diff", req);
65670
+ }
65671
+ // ─── 3. explainDecision ────────────────────────────────────────────────
65672
+ /**
65673
+ * Returns a human-readable explanation of why a decision was made.
65674
+ *
65675
+ * Computed client-side from the omega components and reflex triggers.
65676
+ */
65677
+ async explainDecision(req) {
65678
+ const components = [];
65679
+ if (req.omega_components) {
65680
+ for (const [name, value] of Object.entries(req.omega_components)) {
65681
+ if (typeof value === "number") {
65682
+ components.push({
65683
+ name,
65684
+ value,
65685
+ description: describeComponent(name, value)
65686
+ });
65687
+ }
65688
+ }
65689
+ }
65690
+ const triggers = req.reflex_triggers || [];
65691
+ let summary = `Decision: ${req.decision} (\u03A9_API = ${req.omega_api}).`;
65692
+ if (triggers.length > 0) {
65693
+ summary += ` ${triggers.length} reflex rule(s) triggered.`;
65694
+ }
65695
+ if (req.decision === "BLOCK") {
65696
+ summary += " This change is blocked due to high risk.";
65697
+ } else if (req.decision === "REQUIRE_APPROVAL") {
65698
+ summary += " This change requires manual approval before merging.";
65699
+ } else if (req.decision === "WARN") {
65700
+ summary += " This change has warnings but can proceed.";
65701
+ } else {
65702
+ summary += " This change is safe to proceed.";
65703
+ }
65704
+ return { summary, components };
65705
+ }
65706
+ // ─── 4. howToUnblock ───────────────────────────────────────────────────
65707
+ /**
65708
+ * Returns actionable steps to resolve a BLOCK decision.
65709
+ *
65710
+ * Computed client-side from breaking changes and detected patterns.
65711
+ */
65712
+ async howToUnblock(req) {
65713
+ const actions = [];
65714
+ let step = 1;
65715
+ if (req.decision !== "BLOCK") {
65716
+ actions.push({
65717
+ step: step++,
65718
+ description: `Current decision is "${req.decision}" \u2014 no unblock needed.`
65719
+ });
65720
+ return { actions };
65721
+ }
65722
+ const bcs = req.breaking_changes || [];
65723
+ if (bcs.length > 0) {
65724
+ actions.push({
65725
+ step: step++,
65726
+ description: `Fix ${bcs.length} breaking change(s) in your spec.`,
65727
+ code_example: bcs.slice(0, 3).map((bc) => `# ${bc.type} at ${bc.path}: ${bc.description}`).join("\n")
65728
+ });
65729
+ }
65730
+ const triggers = req.reflex_triggers || [];
65731
+ for (const trigger of triggers) {
65732
+ actions.push({
65733
+ step: step++,
65734
+ description: `Resolve reflex rule: ${trigger.rule}`
65735
+ });
65736
+ }
65737
+ actions.push({
65738
+ step: step++,
65739
+ description: "Request a manual override via POST /api/v1/ledger/:id/override if this is an emergency."
65740
+ });
65741
+ return { actions };
65742
+ }
65743
+ // ─── 5. scoreMcp ──────────────────────────────────────────────────────
65744
+ /**
65745
+ * Score an MCP manifest for agent safety.
65746
+ */
65747
+ async scoreMcp(req) {
65748
+ return this.request("POST", "/api/v1/agent-readiness-score", {
65749
+ spec: req.manifest,
65750
+ spec_type: "mcp"
65751
+ });
65752
+ }
65753
+ // ─── 6. getLedger ─────────────────────────────────────────────────────
65754
+ /**
65755
+ * Query compliance ledger entries.
65756
+ */
65757
+ async getLedger(req = {}) {
65758
+ const params = new URLSearchParams();
65759
+ if (req.repo)
65760
+ params.set("repo", req.repo);
65761
+ if (req.decision)
65762
+ params.set("decision", req.decision);
65763
+ if (req.from)
65764
+ params.set("from", req.from);
65765
+ if (req.to)
65766
+ params.set("to", req.to);
65767
+ if (req.limit)
65768
+ params.set("limit", String(req.limit));
65769
+ const qs = params.toString();
65770
+ const path = `/api/v1/ledger${qs ? `?${qs}` : ""}`;
65771
+ return this.request("GET", path);
65772
+ }
65773
+ // ─── 7. simulatePolicy ───────────────────────────────────────────────
65774
+ /**
65775
+ * Test a YAML policy against two OpenAPI specs.
65776
+ */
65777
+ async simulatePolicy(req) {
65778
+ return this.request("POST", "/api/v1/policy-simulator", req);
65779
+ }
65780
+ // ─── 8. preflightChangeSet ─────────────────────────────────────────────
65781
+ /**
65782
+ * Preflight a multi-artifact change set (OpenAPI / GraphQL / gRPC / AsyncAPI / MCP manifest)
65783
+ * in one call. Returns one aggregated ALLOW/WARN/REQUIRE_APPROVAL/BLOCK decision (strictest-wins)
65784
+ * with per-artifact findings, a bundle fingerprint, and a decision-result.v1.1 envelope +
65785
+ * chain receipt. POST /api/v1/preflight.
65786
+ */
65787
+ async preflightChangeSet(req) {
65788
+ return this.request("POST", "/api/v1/preflight", req);
65789
+ }
65790
+ // ─── 9. verifyReceipt ──────────────────────────────────────────────────
65791
+ /**
65792
+ * Verify a CodeRifts chain receipt's signature and integrity. No API key is required — this is a
65793
+ * public endpoint (the Authorization header is sent for consistency but ignored server-side).
65794
+ * POST /api/v1/verify-receipt.
65795
+ */
65796
+ async verifyReceipt(token) {
65797
+ return this.request("POST", "/api/v1/verify-receipt", { token });
65798
+ }
65799
+ // ─── 10. getDecisionDetails ────────────────────────────────────────────
65800
+ /**
65801
+ * Look up a stored decision by decision_id or fingerprint; returns the stored
65802
+ * decision-result.v1.1 envelope + meta. POST /api/v1/decisions/lookup.
65803
+ */
65804
+ async getDecisionDetails(req) {
65805
+ return this.request("POST", "/api/v1/decisions/lookup", req);
65806
+ }
65807
+ };
65808
+ exports2.CodeRifts = CodeRifts;
65809
+ function describeComponent(name, value) {
65810
+ const descriptions = {
65811
+ S_contract: "Contract severity score \u2014 measures how severe the breaking changes are",
65812
+ P_break: "Break probability \u2014 likelihood that downstream consumers will break",
65813
+ S_blast_eff: "Blast radius \u2014 how many consumers are affected",
65814
+ S_agent: "Agent safety score \u2014 risk to AI agent tool invocations",
65815
+ S_runtime: "Runtime impact \u2014 risk of runtime failures",
65816
+ ECI: "Ecosystem coupling index \u2014 how tightly coupled the API is",
65817
+ M_eff: "Migration effort \u2014 estimated effort to migrate consumers",
65818
+ D_contract: "Contract distance \u2014 semantic distance between old and new contracts",
65819
+ confidence_score: "Confidence in the analysis result"
65820
+ };
65821
+ return descriptions[name] || `${name} = ${value}`;
65822
+ }
65823
+ }
65824
+ });
65825
+
65826
+ // node_modules/@coderifts/sdk/dist/cjs/decision.js
65827
+ var require_decision = __commonJS({
65828
+ "node_modules/@coderifts/sdk/dist/cjs/decision.js"(exports2) {
65829
+ "use strict";
65830
+ Object.defineProperty(exports2, "__esModule", { value: true });
65831
+ exports2.readDecision = readDecision;
65832
+ var EXECUTION_ACTION = {
65833
+ ALLOW: "CONTINUE",
65834
+ WARN: "CONTINUE_WITH_MONITORING",
65835
+ REQUIRE_APPROVAL: "REQUEST_APPROVAL",
65836
+ BLOCK: "STOP"
65837
+ };
65838
+ function isExecutionAction(v) {
65839
+ return v === "CONTINUE" || v === "CONTINUE_WITH_MONITORING" || v === "REQUEST_APPROVAL" || v === "STOP";
65840
+ }
65841
+ function readDecision(response) {
65842
+ if (!response || typeof response !== "object") {
65843
+ return { executionAction: "STOP", decision: null, reason: "UNREADABLE_DECISION" };
65844
+ }
65845
+ const r = response;
65846
+ const env = r.decision_result;
65847
+ if (env && typeof env === "object" && isExecutionAction(env.execution_action)) {
65848
+ const receipt = env.receipt;
65849
+ return {
65850
+ executionAction: env.execution_action,
65851
+ decision: typeof env.decision === "string" ? env.decision : null,
65852
+ envelope: env,
65853
+ receipt: receipt && typeof receipt === "object" ? receipt : void 0
65854
+ };
65855
+ }
65856
+ if (isExecutionAction(r.execution_action)) {
65857
+ return {
65858
+ executionAction: r.execution_action,
65859
+ decision: typeof r.decision === "string" ? r.decision : null
65860
+ };
65861
+ }
65862
+ if (typeof r.decision === "string" && Object.prototype.hasOwnProperty.call(EXECUTION_ACTION, r.decision)) {
65863
+ return { executionAction: EXECUTION_ACTION[r.decision], decision: r.decision };
65864
+ }
65865
+ return {
65866
+ executionAction: "STOP",
65867
+ decision: typeof r.decision === "string" ? r.decision : null,
65868
+ reason: "UNREADABLE_DECISION"
65869
+ };
65870
+ }
65871
+ }
65872
+ });
65873
+
65874
+ // node_modules/@coderifts/sdk/dist/cjs/index.js
65875
+ var require_cjs3 = __commonJS({
65876
+ "node_modules/@coderifts/sdk/dist/cjs/index.js"(exports2) {
65877
+ "use strict";
65878
+ Object.defineProperty(exports2, "__esModule", { value: true });
65879
+ exports2.readDecision = exports2.AuthError = exports2.RateLimitError = exports2.TimeoutError = exports2.ApiError = exports2.CodeRiftsError = exports2.CodeRifts = void 0;
65880
+ var client_js_1 = require_client();
65881
+ Object.defineProperty(exports2, "CodeRifts", { enumerable: true, get: function() {
65882
+ return client_js_1.CodeRifts;
65883
+ } });
65884
+ var errors_js_1 = require_errors5();
65885
+ Object.defineProperty(exports2, "CodeRiftsError", { enumerable: true, get: function() {
65886
+ return errors_js_1.CodeRiftsError;
65887
+ } });
65888
+ Object.defineProperty(exports2, "ApiError", { enumerable: true, get: function() {
65889
+ return errors_js_1.ApiError;
65890
+ } });
65891
+ Object.defineProperty(exports2, "TimeoutError", { enumerable: true, get: function() {
65892
+ return errors_js_1.TimeoutError;
65893
+ } });
65894
+ Object.defineProperty(exports2, "RateLimitError", { enumerable: true, get: function() {
65895
+ return errors_js_1.RateLimitError;
65896
+ } });
65897
+ Object.defineProperty(exports2, "AuthError", { enumerable: true, get: function() {
65898
+ return errors_js_1.AuthError;
65899
+ } });
65900
+ var decision_js_1 = require_decision();
65901
+ Object.defineProperty(exports2, "readDecision", { enumerable: true, get: function() {
65902
+ return decision_js_1.readDecision;
65903
+ } });
65904
+ }
65905
+ });
65906
+
65907
+ // node_modules/@coderifts/agent-guard/dist/cjs/detector.js
65908
+ var require_detector = __commonJS({
65909
+ "node_modules/@coderifts/agent-guard/dist/cjs/detector.js"(exports2) {
65910
+ "use strict";
65911
+ Object.defineProperty(exports2, "__esModule", { value: true });
65912
+ exports2.builtinDetector = exports2.DETECTOR_VERSION = void 0;
65913
+ var node_zlib_1 = require("node:zlib");
65914
+ exports2.DETECTOR_VERSION = "builtin/1.1.0";
65915
+ var CONTRACT_PATH_RE = [
65916
+ /openapi/i,
65917
+ /swagger/i,
65918
+ /asyncapi/i,
65919
+ /\.graphql$/i,
65920
+ /\.gql$/i,
65921
+ /\.proto$/i,
65922
+ /\.pb($|\.)/i,
65923
+ /(^|\/)[\w.-]*mcp[\w.-]*\.json$/i,
65924
+ /tools-catalog\.json$/i,
65925
+ /schema\.prisma$/i,
65926
+ /(^|\/)migrations?\//i,
65927
+ /(^|\/)alembic\//i,
65928
+ /(^|\/)buf\.ya?ml$/i,
65929
+ /\.spectral\.ya?ml$/i,
65930
+ /(^|\/)\.github\/workflows\//i,
65931
+ /(^|\/)\.husky\//i,
65932
+ /api[-_]?contract/i,
65933
+ /service-definition/i,
65934
+ /(^|\/)contracts?\//i,
65935
+ /schemas?\/components?\//i,
65936
+ /\bcontract\.json$/i,
65937
+ /(^|\/)spec\.(ya?ml|json)$/i,
65938
+ /api[-_/]spec\.(ya?ml|json)$/i,
65939
+ /-api\.(ya?ml|yml)$/i,
65940
+ /current-api/i,
65941
+ /(^|\/)(src\/)?generated\//i,
65942
+ /(^|\/)gen\//i,
65943
+ /\.pb\.go$/i,
65944
+ /openapi\.d\.ts$/i
65945
+ ];
65946
+ var NON_SSOT_PATH_RE = [
65947
+ /(^|\/)tests?\//i,
65948
+ /(^|\/)__tests__\//i,
65949
+ /(^|\/)__mocks__\//i,
65950
+ /\/fixtures?\//i,
65951
+ /(^|\/)mocks?\//i,
65952
+ /\.test\.[jt]sx?$/i,
65953
+ /\.spec\.[jt]sx?$/i,
65954
+ /(^|\/)src\/internal\//i,
65955
+ /(^|\/)node_modules\//i
65956
+ ];
65957
+ var PROSE_PATH_RE = [/(^|\/)README(\.\w+)?$/i, /(^|\/)CHANGELOG(\.\w+)?$/i, /(^|\/)LICENSE(\.\w+)?$/i, /\.md$/i];
65958
+ var CODE_CONTRACT_PATH_RE = [/(^|\/)src\/routes?\//i, /(^|\/)routes?\//i, /(^|\/)app\/api\//i, /(^|\/)src\/dto\//i, /dto/i, /routers?\//i, /\.prisma$/i, /\.tf$/i, /server\/routers?\//i];
65959
+ var GATE_PATH_RE = [/(^|\/)\.github\/workflows\//i, /(^|\/)\.husky\//i, /\.spectral\.ya?ml$/i, /(^|\/)buf\.ya?ml$/i];
65960
+ var LOCKFILE_RE = /(package-lock\.json|pnpm-lock\.ya?ml|yarn\.lock|composer\.lock|Cargo\.lock)$/i;
65961
+ var CONTRACT_CONTENT_RE = [
65962
+ /\bopenapi\s*[:=]\s*["']?3/i,
65963
+ /["']openapi["']\s*:/i,
65964
+ /\bswagger\s*[:=]/i,
65965
+ /["']swagger["']\s*:/i,
65966
+ /\basyncapi\s*[:=]/i,
65967
+ /["']asyncapi["']\s*:/i,
65968
+ /(^|\n)\s*paths\s*:/i,
65969
+ /["']paths["']\s*:/i,
65970
+ /syntax\s*=\s*["']proto3/i,
65971
+ /(^|\n)\s*message\s+\w+\s*\{/i,
65972
+ /\btype\s+(Query|Mutation|Subscription)\b/i,
65973
+ /["']tools["']\s*:\s*\[/i,
65974
+ /["']inputSchema["']\s*:/i,
65975
+ /\/v\d+\/[\w{}.-]*\s*:/,
65976
+ // versioned route-path key
65977
+ /\bchannels\s*:/i
65978
+ ];
65979
+ var CONTRACT_STRUCTURE_RE = [
65980
+ /(get|post|put|delete|patch)\s*:\s*\{?/i,
65981
+ /message\s+\w+\s*\{[^}]*=\s*\d+/i,
65982
+ /\/v\d+\/[\w{}.-]*\s*:/,
65983
+ /"name"\s*:\s*"[^"]+"[\s,}]*"?inputSchema/i
65984
+ ];
65985
+ var REAL_CHANGE_RE = [
65986
+ /required\s*:\s*\[/i,
65987
+ /["']required["']\s*:\s*\[/i,
65988
+ /\btype\s*:\s*\w+/i,
65989
+ /nullable\s*:/i,
65990
+ /:\s*\w+!/,
65991
+ /additionalProperties\s*:\s*(true|false)/i,
65992
+ /["']additionalProperties["']/i,
65993
+ /\bDROP\s+COLUMN\b/i,
65994
+ /\bALTER\s+COLUMN\b/i,
65995
+ /alter_column\s*\(/i,
65996
+ /new_column_name/i,
65997
+ /\bRENAME\b/i,
65998
+ /DROP\s+TABLE/i,
65999
+ /@IsString|@IsOptional|response_model|z\.string|@unique/i,
66000
+ /app\.(get|post|put|delete|patch)\s*\(/i,
66001
+ /@router\.(get|post|put|delete|patch)/i,
66002
+ /\/v\d+\//,
66003
+ /continue-on-error|if:\s*false|:\s*off\b|'off'|"off"/i,
66004
+ /\bignore\s*:/i,
66005
+ /(^|\n)\s*breaking\s*:/i
66006
+ ];
66007
+ var INERT_KEY_RE = [
66008
+ /^description\s*:/i,
66009
+ /^["']description["']\s*:/i,
66010
+ /^summary\s*:/i,
66011
+ /^title\s*:/i,
66012
+ /^contact\s*:/i,
66013
+ /^name\s*:/i,
66014
+ /^examples?\s*:/i,
66015
+ /^["']examples?["']\s*:/i,
66016
+ /^x-[\w-]+\s*:/i,
66017
+ /^["']x-[\w-]+["']\s*:/i
66018
+ ];
66019
+ var READ_ONLY_TOOLS = /* @__PURE__ */ new Set(["read", "grep", "glob", "ls", "cat", "view", "search", "list", "get"]);
66020
+ var FORMATTER_RE = /\b(prettier|eslint\s+--fix|gofmt|rustfmt|black|clang-format|dprint)\b/i;
66021
+ var GATE_KEYWORD_RE = /coderifts|agent-guard|contract-check|contract\b|preflight|spectral|\bbuf\b/i;
66022
+ function anyMatch(res, s) {
66023
+ return res.some((r) => r.test(s));
66024
+ }
66025
+ function argString(args) {
66026
+ if (args == null)
66027
+ return "";
66028
+ if (typeof args === "string")
66029
+ return args;
66030
+ try {
66031
+ return JSON.stringify(args);
66032
+ } catch {
66033
+ return "";
66034
+ }
66035
+ }
66036
+ function changeText(call) {
66037
+ const parts = [];
66038
+ if (call.diff)
66039
+ parts.push(call.diff);
66040
+ const a = call.arguments;
66041
+ if (a && typeof a === "object") {
66042
+ for (const k of ["new_string", "old_string", "contents", "content", "patch", "command"]) {
66043
+ const v = a[k];
66044
+ if (typeof v === "string")
66045
+ parts.push(v);
66046
+ }
66047
+ const edits = a.edits;
66048
+ if (Array.isArray(edits))
66049
+ for (const e of edits)
66050
+ parts.push(argString(e));
66051
+ }
66052
+ return parts.join("\n");
66053
+ }
66054
+ function commandText(call) {
66055
+ const a = call.arguments;
66056
+ const c = a && typeof a === "object" ? a.command : void 0;
66057
+ return typeof c === "string" ? c : "";
66058
+ }
66059
+ function allPaths(call) {
66060
+ const out = [...call.filesTouched || []];
66061
+ const a = call.arguments;
66062
+ if (a && typeof a === "object" && typeof a.path === "string")
66063
+ out.push(a.path);
66064
+ return out;
66065
+ }
66066
+ function isContractPath(p) {
66067
+ if (anyMatch(NON_SSOT_PATH_RE, p))
66068
+ return false;
66069
+ if (anyMatch(PROSE_PATH_RE, p))
66070
+ return false;
66071
+ return anyMatch(CONTRACT_PATH_RE, p);
66072
+ }
66073
+ function changedLines(call) {
66074
+ if (call.diff) {
66075
+ return call.diff.split("\n").filter((l) => l.startsWith("+") || l.startsWith("-")).map((l) => l.slice(1));
66076
+ }
66077
+ const out = [];
66078
+ const a = call.arguments;
66079
+ const pushSetDiff = (oldS, newS) => {
66080
+ const oldL = typeof oldS === "string" ? oldS.split("\n") : [];
66081
+ const newL = typeof newS === "string" ? newS.split("\n") : [];
66082
+ const oldSet = new Set(oldL.map((l) => l.trim()));
66083
+ const newSet = new Set(newL.map((l) => l.trim()));
66084
+ for (const l of newL)
66085
+ if (!oldSet.has(l.trim()))
66086
+ out.push(l);
66087
+ for (const l of oldL)
66088
+ if (!newSet.has(l.trim()))
66089
+ out.push(l);
66090
+ };
66091
+ if (a && typeof a === "object") {
66092
+ pushSetDiff(a.old_string, a.new_string);
66093
+ const contents = a.contents ?? a.content;
66094
+ if (typeof contents === "string")
66095
+ for (const l of contents.split("\n"))
66096
+ out.push(l);
66097
+ const patch = a.patch;
66098
+ if (typeof patch === "string") {
66099
+ for (const l of patch.split("\n"))
66100
+ if (l.startsWith("+") || l.startsWith("-"))
66101
+ out.push(l.slice(1));
66102
+ }
66103
+ const edits = a.edits;
66104
+ if (Array.isArray(edits)) {
66105
+ for (const e of edits)
66106
+ if (e && typeof e === "object")
66107
+ pushSetDiff(e.old_string, e.new_string);
66108
+ }
66109
+ }
66110
+ return out;
66111
+ }
66112
+ function migrationDestructive(text) {
66113
+ return /\bDROP\s+COLUMN\b|\bALTER\s+COLUMN\b|new_column_name|alter_column|\bRENAME\b|DROP\s+TABLE|DROP\s+CONSTRAINT/i.test(text);
66114
+ }
66115
+ function migrationIndexOnly(text) {
66116
+ return /CREATE\s+INDEX/i.test(text) && !migrationDestructive(text) && !/ADD\s+COLUMN|DROP\b/i.test(text);
66117
+ }
66118
+ function gateDisabled(call) {
66119
+ const paths = allPaths(call);
66120
+ if (!paths.some((p) => anyMatch(GATE_PATH_RE, p)))
66121
+ return false;
66122
+ const text = changeText(call);
66123
+ if (!GATE_KEYWORD_RE.test(text))
66124
+ return false;
66125
+ const lines = changedLines(call);
66126
+ const commentedOut = lines.some((l) => /^\s*(#|\/\/)/.test(l) && GATE_KEYWORD_RE.test(l));
66127
+ const weakened = anyMatch(REAL_CHANGE_RE, text) || /continue-on-error|if:\s*false|:\s*off\b|ignore\s*:/i.test(text);
66128
+ return commentedOut || weakened;
66129
+ }
66130
+ function lockfileContractChange(call) {
66131
+ const paths = allPaths(call);
66132
+ if (!paths.some((p) => LOCKFILE_RE.test(p)))
66133
+ return false;
66134
+ const text = changeText(call);
66135
+ const contractPkg = /@[\w.-]+\/(openapi|graphql|proto|asyncapi|schema)\b|(openapi|graphql|proto|asyncapi|schema)@\d/i.test(text);
66136
+ if (!contractPkg)
66137
+ return false;
66138
+ return /"resolved"\s*:/i.test(text) || /@\d+\.\d+\.\d+/.test(text) || /@\d+['":]/.test(text);
66139
+ }
66140
+ function isInertOnly(call) {
66141
+ const text = changeText(call);
66142
+ const paths = allPaths(call);
66143
+ if (paths.some((p) => LOCKFILE_RE.test(p)) && !lockfileContractChange(call)) {
66144
+ if (/"integrity"\s*:/i.test(text) && !/"resolved"\s*:/i.test(text))
66145
+ return true;
66146
+ }
66147
+ if (paths.some((p) => /migrations?\/|alembic\//i.test(p)) && migrationIndexOnly(text))
66148
+ return true;
66149
+ if (paths.some((p) => anyMatch(GATE_PATH_RE, p))) {
66150
+ if (!GATE_KEYWORD_RE.test(text) && !anyMatch(REAL_CHANGE_RE, text))
66151
+ return true;
66152
+ return false;
66153
+ }
66154
+ const cmd = commandText(call);
66155
+ if (cmd && FORMATTER_RE.test(cmd))
66156
+ return true;
66157
+ if (/\b(examples?|value)\s*:/i.test(text) && !anyMatch(REAL_CHANGE_RE, text))
66158
+ return true;
66159
+ const lines = changedLines(call);
66160
+ if (lines.length === 0)
66161
+ return false;
66162
+ let sawReal = false;
66163
+ let sawInert = false;
66164
+ for (const raw of lines) {
66165
+ const t = raw.trim();
66166
+ if (t === "") {
66167
+ sawInert = true;
66168
+ continue;
66169
+ }
66170
+ if (/^#|^\/\/|^\/\*|\*\/|^\*/.test(t)) {
66171
+ sawInert = true;
66172
+ continue;
66173
+ }
66174
+ if (/^```/.test(t)) {
66175
+ sawInert = true;
66176
+ continue;
66177
+ }
66178
+ if (/^["'].*["']$/.test(t) && !t.includes(":")) {
66179
+ sawInert = true;
66180
+ continue;
66181
+ }
66182
+ if (/generated|timestamp/i.test(t)) {
66183
+ sawInert = true;
66184
+ continue;
66185
+ }
66186
+ if (anyMatch(INERT_KEY_RE, t)) {
66187
+ sawInert = true;
66188
+ continue;
66189
+ }
66190
+ if (anyMatch(REAL_CHANGE_RE, t) || anyMatch(CONTRACT_STRUCTURE_RE, t) || anyMatch(CONTRACT_CONTENT_RE, t)) {
66191
+ sawReal = true;
66192
+ continue;
66193
+ }
66194
+ if (/^[\w"']+\??\s*:\s*\S/.test(t)) {
66195
+ sawReal = true;
66196
+ continue;
66197
+ }
66198
+ }
66199
+ return sawInert && !sawReal;
66200
+ }
66201
+ function realChangePresent(call) {
66202
+ const text = changeText(call);
66203
+ if (migrationDestructive(text))
66204
+ return true;
66205
+ if (gateDisabled(call))
66206
+ return true;
66207
+ if (lockfileContractChange(call))
66208
+ return true;
66209
+ for (const raw of changedLines(call)) {
66210
+ const t = raw.trim();
66211
+ if (anyMatch(INERT_KEY_RE, t))
66212
+ continue;
66213
+ if (anyMatch(REAL_CHANGE_RE, t))
66214
+ return true;
66215
+ if (/^[\w"']+\??\s*:\s*\S/.test(t) && !/^(paths|components|info|servers|channels|tools|get|post|put|delete|patch)\s*:/i.test(t))
66216
+ return true;
66217
+ }
66218
+ return false;
66219
+ }
66220
+ function intentMentionsContract(intent) {
66221
+ if (!intent)
66222
+ return false;
66223
+ return /openapi|swagger|graphql|protobuf|\bproto\b|asyncapi|mcp\s*manifest|mcp\.json|json\s*schema|\bschema\b|required\s+field|\bendpoint\b|wire\s*format|api\s*spec|contract\s*(file|change|surface)/i.test(intent);
66224
+ }
66225
+ function commandMutatesContract(call) {
66226
+ const cmd = commandText(call);
66227
+ if (!cmd)
66228
+ return false;
66229
+ if (FORMATTER_RE.test(cmd))
66230
+ return false;
66231
+ const touchesContract = allPaths(call).some(isContractPath) || /(>|>>|-o\s|mv\s|ln\s+-sf?\s|git\s+mv\s|cp\s)[^\n|]*(openapi|swagger|asyncapi|\.graphql|\.gql|\.proto|\.pb\b|mcp[.-]?\w*\.json|schema\.prisma|spec\.(ya?ml|json))/i.test(cmd) || anyMatch(CONTRACT_CONTENT_RE, cmd);
66232
+ const mutates = /(>|>>|\bmv\b|\bcp\b|\bln\s|git\s+mv|curl|wget|-o\b|base64\s+-d|xxd|\bjq\b|\bsed\b|\btee\b|echo|printf|\bcat\b)/i.test(cmd);
66233
+ return touchesContract && mutates;
66234
+ }
66235
+ var DEEP_MAX_DEPTH = 8;
66236
+ var DEEP_MAX_BYTES = 262144;
66237
+ var DEEP_DECODE_MAX_BYTES = 65536;
66238
+ var DEEP_DECODE_LEVELS = 3;
66239
+ var OPAQUE_MIN_LEN = 40;
66240
+ function looksLikePath(v) {
66241
+ return v.length > 0 && v.length <= 256 && !/[\n\r{}<>]/.test(v) && /(^|\/)[\w.@-]+\.[A-Za-z0-9]+$/.test(v.trim());
66242
+ }
66243
+ function decodeCandidates(v) {
66244
+ const out = [];
66245
+ const push = (s) => {
66246
+ if (s && s.length > 0 && s.length <= DEEP_DECODE_MAX_BYTES)
66247
+ out.push(s);
66248
+ };
66249
+ const compact = v.replace(/\s+/g, "");
66250
+ if (compact.length >= 16 && compact.length % 4 === 0 && /^[A-Za-z0-9+/]+={0,2}$/.test(compact)) {
66251
+ try {
66252
+ push(Buffer.from(compact, "base64").toString("utf8"));
66253
+ } catch {
66254
+ }
66255
+ try {
66256
+ const b = Buffer.from(compact, "base64");
66257
+ push((0, node_zlib_1.gunzipSync)(b).toString("utf8"));
66258
+ } catch {
66259
+ }
66260
+ }
66261
+ if (compact.length >= 16 && compact.length % 2 === 0 && /^[0-9a-fA-F]+$/.test(compact)) {
66262
+ try {
66263
+ push(Buffer.from(compact, "hex").toString("utf8"));
66264
+ } catch {
66265
+ }
66266
+ }
66267
+ if (/%[0-9a-fA-F]{2}/.test(v)) {
66268
+ try {
66269
+ push(decodeURIComponent(v));
66270
+ } catch {
66271
+ }
66272
+ }
66273
+ if (/\\["\\/]|^\s*"/.test(v)) {
66274
+ try {
66275
+ const p = JSON.parse(v);
66276
+ if (typeof p === "string")
66277
+ push(p);
66278
+ } catch {
66279
+ }
66280
+ }
66281
+ return out;
66282
+ }
66283
+ function looksEncoded(v) {
66284
+ const c = v.replace(/\s+/g, "");
66285
+ if (c.length < OPAQUE_MIN_LEN)
66286
+ return false;
66287
+ return /^[A-Za-z0-9+/]+={0,2}$/.test(c) && c.length % 4 === 0 || /^[0-9a-fA-F]+$/.test(c) && c.length % 2 === 0;
66288
+ }
66289
+ function deepArgScan(call) {
66290
+ const acc = { contractContent: false, pathContractSsot: false, pathNonSsot: false, pathLikeCount: 0, proseCount: 0, opaque: false, capHit: false };
66291
+ let budget = DEEP_MAX_BYTES;
66292
+ const scanString = (s) => {
66293
+ if (looksLikePath(s)) {
66294
+ acc.pathLikeCount++;
66295
+ if (anyMatch(NON_SSOT_PATH_RE, s))
66296
+ acc.pathNonSsot = true;
66297
+ else if (anyMatch(PROSE_PATH_RE, s))
66298
+ acc.proseCount++;
66299
+ else if (isContractPath(s))
66300
+ acc.pathContractSsot = true;
66301
+ return;
66302
+ }
66303
+ if (anyMatch(CONTRACT_CONTENT_RE, s) || anyMatch(CONTRACT_STRUCTURE_RE, s)) {
66304
+ acc.contractContent = true;
66305
+ return;
66306
+ }
66307
+ let level = [s];
66308
+ for (let d = 0; d < DEEP_DECODE_LEVELS && !acc.contractContent; d++) {
66309
+ const next = [];
66310
+ for (const val of level) {
66311
+ for (const dec of decodeCandidates(val)) {
66312
+ if (anyMatch(CONTRACT_CONTENT_RE, dec) || anyMatch(CONTRACT_STRUCTURE_RE, dec)) {
66313
+ acc.contractContent = true;
66314
+ break;
66315
+ }
66316
+ next.push(dec);
66317
+ }
66318
+ if (acc.contractContent)
66319
+ break;
66320
+ }
66321
+ level = next;
66322
+ }
66323
+ if (!acc.contractContent && looksEncoded(s) && level.every((x) => !isReadableText(x)))
66324
+ acc.opaque = true;
66325
+ };
66326
+ const walk = (node, depth) => {
66327
+ if (acc.capHit || budget <= 0)
66328
+ return;
66329
+ if (depth > DEEP_MAX_DEPTH) {
66330
+ acc.capHit = true;
66331
+ return;
66332
+ }
66333
+ if (typeof node === "string") {
66334
+ budget -= node.length;
66335
+ if (budget <= 0) {
66336
+ acc.capHit = true;
66337
+ return;
66338
+ }
66339
+ scanString(node);
66340
+ } else if (Array.isArray(node)) {
66341
+ for (const el of node) {
66342
+ if (acc.capHit)
66343
+ break;
66344
+ walk(el, depth + 1);
66345
+ }
66346
+ } else if (node && typeof node === "object") {
66347
+ for (const val of Object.values(node)) {
66348
+ if (acc.capHit)
66349
+ break;
66350
+ walk(val, depth + 1);
66351
+ }
66352
+ }
66353
+ };
66354
+ try {
66355
+ walk(call.arguments, 0);
66356
+ } catch {
66357
+ acc.capHit = true;
66358
+ }
66359
+ return acc;
66360
+ }
66361
+ function isReadableText(s) {
66362
+ if (!s)
66363
+ return false;
66364
+ let printable = 0;
66365
+ const n = Math.min(s.length, 512);
66366
+ for (let i = 0; i < n; i++) {
66367
+ const c = s.charCodeAt(i);
66368
+ if (c === 9 || c === 10 || c === 13 || c >= 32 && c < 127)
66369
+ printable++;
66370
+ }
66371
+ return printable / n > 0.85;
66372
+ }
66373
+ exports2.builtinDetector = {
66374
+ version: exports2.DETECTOR_VERSION,
66375
+ detect(call) {
66376
+ const signals = [];
66377
+ const artifacts = Array.isArray(call.artifacts) ? call.artifacts : [];
66378
+ if (artifacts.length > 0)
66379
+ return { trigger: true, artifacts, signals: ["explicit_artifacts"], confident: true };
66380
+ if (READ_ONLY_TOOLS.has(String(call.toolName).toLowerCase()) && !commandMutatesContract(call)) {
66381
+ return { trigger: false, artifacts: [], signals: ["non_mutating_tool"], confident: true };
66382
+ }
66383
+ const paths = allPaths(call);
66384
+ const contractPath = paths.some(isContractPath);
66385
+ const codeContractPath = paths.some((p) => anyMatch(CODE_CONTRACT_PATH_RE, p) && !anyMatch(NON_SSOT_PATH_RE, p));
66386
+ const change = changeText(call);
66387
+ const inProse = paths.length > 0 && paths.every((p) => anyMatch(PROSE_PATH_RE, p));
66388
+ const contentMarker = anyMatch(CONTRACT_CONTENT_RE, change) && !paths.some((p) => anyMatch(NON_SSOT_PATH_RE, p)) && !inProse;
66389
+ const shellMutation = commandMutatesContract(call);
66390
+ const gate = gateDisabled(call);
66391
+ const lockContract = lockfileContractChange(call);
66392
+ const contractSurface = contractPath || contentMarker || shellMutation || codeContractPath || gate || lockContract;
66393
+ if (contractSurface) {
66394
+ if (shellMutation) {
66395
+ signals.push("shell_mutates_contract");
66396
+ return { trigger: true, artifacts, signals, confident: true };
66397
+ }
66398
+ if (gate) {
66399
+ signals.push("contract_gate_disabled");
66400
+ return { trigger: true, artifacts, signals, confident: true };
66401
+ }
66402
+ if (lockContract) {
66403
+ signals.push("lockfile_contract_redirect");
66404
+ return { trigger: true, artifacts, signals, confident: true };
66405
+ }
66406
+ if (isInertOnly(call)) {
66407
+ signals.push("inert_change_only");
66408
+ return { trigger: false, artifacts: [], signals, confident: true };
66409
+ }
66410
+ if (realChangePresent(call) || contentMarker || anyMatch(CONTRACT_STRUCTURE_RE, change)) {
66411
+ signals.push("contract_change");
66412
+ return { trigger: true, artifacts, signals, confident: true };
66413
+ }
66414
+ signals.push("ambiguous_contract_surface");
66415
+ return { trigger: true, artifacts, signals, confident: false };
66416
+ }
66417
+ const deep = deepArgScan(call);
66418
+ if (deep.contractContent || deep.pathContractSsot) {
66419
+ const deepInProse = deep.pathLikeCount > 0 && deep.proseCount === deep.pathLikeCount && !deep.pathContractSsot;
66420
+ if (!deep.pathNonSsot && !deepInProse && !isInertOnly(call)) {
66421
+ signals.push(deep.contractContent ? "arguments_deep_contract" : "arguments_deep_path");
66422
+ return { trigger: true, artifacts, signals, confident: false };
66423
+ }
66424
+ }
66425
+ if (deep.opaque || deep.capHit) {
66426
+ signals.push(deep.capHit ? "arguments_scan_capped" : "arguments_opaque");
66427
+ return { trigger: true, artifacts, signals, confident: false };
66428
+ }
66429
+ if (intentMentionsContract(call.intent)) {
66430
+ signals.push("intent_contract_reference");
66431
+ return { trigger: true, artifacts, signals, confident: false };
66432
+ }
66433
+ signals.push("no_contract_signal");
66434
+ return { trigger: false, artifacts: [], signals, confident: true };
66435
+ }
66436
+ };
66437
+ }
66438
+ });
66439
+
66440
+ // node_modules/@coderifts/agent-guard/dist/cjs/receipt-binding.js
66441
+ var require_receipt_binding = __commonJS({
66442
+ "node_modules/@coderifts/agent-guard/dist/cjs/receipt-binding.js"(exports2) {
66443
+ "use strict";
66444
+ Object.defineProperty(exports2, "__esModule", { value: true });
66445
+ exports2.canonicalJson = canonicalJson;
66446
+ exports2.computeBodyHash = computeBodyHash;
66447
+ exports2.bindReceiptToEnvelope = bindReceiptToEnvelope;
66448
+ var node_crypto_1 = require("node:crypto");
66449
+ function canonicalJson(value) {
66450
+ return encode(value);
66451
+ }
66452
+ function encode(value) {
66453
+ if (value === null)
66454
+ return "null";
66455
+ const t = typeof value;
66456
+ if (t === "boolean" || t === "string")
66457
+ return JSON.stringify(value);
66458
+ if (t === "number") {
66459
+ if (!Number.isFinite(value))
66460
+ throw new TypeError("canonicalJson: non-finite number is not representable");
66461
+ return JSON.stringify(value);
66462
+ }
66463
+ if (t === "undefined")
66464
+ throw new TypeError("canonicalJson: undefined is not representable (omit the key instead)");
66465
+ if (Array.isArray(value))
66466
+ return `[${value.map(encode).join(",")}]`;
66467
+ if (t === "object") {
66468
+ const obj = value;
66469
+ const keys = Object.keys(obj).sort();
66470
+ return `{${keys.map((k) => `${JSON.stringify(k)}:${encode(obj[k])}`).join(",")}}`;
66471
+ }
66472
+ throw new TypeError(`canonicalJson: unsupported type ${t}`);
66473
+ }
66474
+ function sha256hex(s) {
66475
+ return (0, node_crypto_1.createHash)("sha256").update(s).digest("hex");
66476
+ }
66477
+ function computeBodyHash(envelope) {
66478
+ const rest = { ...envelope };
66479
+ delete rest.receipt;
66480
+ delete rest.decision_body_hash;
66481
+ return `sha256:${sha256hex(canonicalJson(rest))}`;
66482
+ }
66483
+ function bindReceiptToEnvelope(envelope, vr, ctx = {}) {
66484
+ if (!envelope)
66485
+ return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: "no envelope" };
66486
+ if (!vr || vr.valid !== true)
66487
+ return { ok: false, cause: "RECEIPT_UNVERIFIED", detail: `valid=${vr ? vr.valid : "none"}` };
66488
+ if (vr.status !== "VERIFIED_CURRENT") {
66489
+ return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: `status ${vr.status ?? "unknown"} != VERIFIED_CURRENT` };
66490
+ }
66491
+ const payload = vr.payload || {};
66492
+ const localBh = computeBodyHash(envelope);
66493
+ if (typeof payload.bh !== "string" || payload.bh !== localBh) {
66494
+ return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: "decision_body_hash mismatch (receipt was signed over a different envelope)" };
66495
+ }
66496
+ if (typeof payload.fp !== "string" || payload.fp !== envelope.fingerprint) {
66497
+ return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: "verdict_fingerprint mismatch" };
66498
+ }
66499
+ const requestedOp = ctx.operation ?? "tool_call";
66500
+ if (envelope.operation != null && requestedOp != null && envelope.operation !== requestedOp) {
66501
+ return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: `operation ${String(envelope.operation)} != ${String(requestedOp)}` };
66502
+ }
66503
+ if (ctx.environment != null && envelope.environment != null && envelope.environment !== ctx.environment) {
66504
+ return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: `environment ${String(envelope.environment)} != ${String(ctx.environment)}` };
66505
+ }
66506
+ if (ctx.audience != null && envelope.audience != null && envelope.audience !== ctx.audience) {
66507
+ return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: `audience ${String(envelope.audience)} != ${String(ctx.audience)}` };
66508
+ }
66509
+ return { ok: true };
66510
+ }
66511
+ }
66512
+ });
66513
+
66514
+ // node_modules/@coderifts/agent-guard/dist/cjs/enforcement-gate.js
66515
+ var require_enforcement_gate = __commonJS({
66516
+ "node_modules/@coderifts/agent-guard/dist/cjs/enforcement-gate.js"(exports2) {
66517
+ "use strict";
66518
+ Object.defineProperty(exports2, "__esModule", { value: true });
66519
+ exports2.computeArtifactDigest = computeArtifactDigest;
66520
+ exports2.computeBundleFingerprint = computeBundleFingerprint;
66521
+ exports2.evaluateEnvelope = evaluateEnvelope;
66522
+ var node_crypto_1 = require("node:crypto");
66523
+ var DECISION_RANK = { ALLOW: 0, WARN: 1, REQUIRE_APPROVAL: 2, BLOCK: 3 };
66524
+ var ACTION_TO_DECISION = {
66525
+ CONTINUE: "ALLOW",
66526
+ CONTINUE_WITH_MONITORING: "WARN",
66527
+ REQUEST_APPROVAL: "REQUIRE_APPROVAL",
66528
+ STOP: "BLOCK"
66529
+ };
66530
+ var DECISION_TO_ACTION = {
66531
+ ALLOW: "CONTINUE",
66532
+ WARN: "CONTINUE_WITH_MONITORING",
66533
+ REQUIRE_APPROVAL: "REQUEST_APPROVAL",
66534
+ BLOCK: "STOP"
66535
+ };
66536
+ function isDecision(v) {
66537
+ return v === "ALLOW" || v === "WARN" || v === "REQUIRE_APPROVAL" || v === "BLOCK";
66538
+ }
66539
+ function isAction(v) {
66540
+ return v === "CONTINUE" || v === "CONTINUE_WITH_MONITORING" || v === "REQUEST_APPROVAL" || v === "STOP";
66541
+ }
66542
+ var NUL = "";
66543
+ function sha256hex(s) {
66544
+ return (0, node_crypto_1.createHash)("sha256").update(s).digest("hex");
66545
+ }
66546
+ function specStr(v) {
66547
+ return v == null ? "" : typeof v === "string" ? v : JSON.stringify(v);
66548
+ }
66549
+ function computeArtifactDigest(artifacts) {
66550
+ const preimage = artifacts.slice().sort((a, b) => `${a.type}${NUL}${a.id}` < `${b.type}${NUL}${b.id}` ? -1 : 1).map((a) => `${sha256hex(specStr(a.before))}${sha256hex(specStr(a.after))}`).join(NUL);
66551
+ return `sha256:${sha256hex(preimage)}`;
66552
+ }
66553
+ function computeBundleFingerprint(artifacts) {
66554
+ const parts = artifacts.slice().sort((a, b) => `${a.type}${NUL}${a.id}` < `${b.type}${NUL}${b.id}` ? -1 : 1).map((a) => [a.type, a.id, sha256hex(specStr(a.before)), sha256hex(specStr(a.after))].join(NUL));
66555
+ return `sha256:${sha256hex(parts.join(NUL))}`;
66556
+ }
66557
+ function evaluateEnvelope(response, envelope, executionAction, sentArtifacts) {
66558
+ const dec = envelope.decision;
66559
+ if (!isDecision(dec)) {
66560
+ return { verdict: "fail-closed", cause: "DECISION_INCONSISTENT", detail: `decision=${JSON.stringify(dec)} is missing/invalid` };
66561
+ }
66562
+ const signals = [dec, ACTION_TO_DECISION[executionAction]];
66563
+ const top = response && typeof response === "object" ? response : {};
66564
+ if (isDecision(top.decision))
66565
+ signals.push(top.decision);
66566
+ if (isAction(top.execution_action))
66567
+ signals.push(ACTION_TO_DECISION[top.execution_action]);
66568
+ const effective = signals.reduce((a, b) => DECISION_RANK[b] > DECISION_RANK[a] ? b : a);
66569
+ if (DECISION_RANK[effective] >= DECISION_RANK.REQUIRE_APPROVAL) {
66570
+ return { verdict: "block-strict", decision: effective };
66571
+ }
66572
+ if (DECISION_TO_ACTION[dec] !== executionAction) {
66573
+ return { verdict: "fail-closed", cause: "DECISION_INCONSISTENT", detail: `decision=${dec} \u2260 execution_action=${executionAction}` };
66574
+ }
66575
+ if (envelope.safe_for_agent === false) {
66576
+ return { verdict: "fail-closed", cause: "DECISION_INCONSISTENT", detail: "safe_for_agent=false on an allow-class decision" };
66577
+ }
66578
+ const degradedReasons = envelope.degraded_reasons;
66579
+ if (envelope.analysis_complete === false || Array.isArray(degradedReasons) && degradedReasons.length > 0 || envelope.degraded === true || envelope.coverage_gap === true) {
66580
+ return { verdict: "fail-closed", cause: "ANALYSIS_DEGRADED", detail: "analysis degraded / incomplete" };
66581
+ }
66582
+ if (Array.isArray(sentArtifacts) && sentArtifacts.length > 0 && typeof envelope.artifact_digest === "string" && envelope.artifact_digest !== computeArtifactDigest(sentArtifacts)) {
66583
+ return { verdict: "fail-closed", cause: "ARTIFACT_MISMATCH", detail: "artifact_digest \u2260 locally-recomputed digest of sent artifacts" };
66584
+ }
66585
+ return { verdict: "allow", kind: effective === "ALLOW" ? "ALLOW" : "MONITOR" };
66586
+ }
66587
+ }
66588
+ });
66589
+
66590
+ // node_modules/@coderifts/agent-guard/dist/cjs/guard.js
66591
+ var require_guard = __commonJS({
66592
+ "node_modules/@coderifts/agent-guard/dist/cjs/guard.js"(exports2) {
66593
+ "use strict";
66594
+ Object.defineProperty(exports2, "__esModule", { value: true });
66595
+ exports2.guardToolCall = guardToolCall;
66596
+ var node_crypto_1 = require("node:crypto");
66597
+ var sdk_1 = require_cjs3();
66598
+ var detector_js_1 = require_detector();
66599
+ var receipt_binding_js_1 = require_receipt_binding();
66600
+ var enforcement_gate_js_1 = require_enforcement_gate();
66601
+ var breakers = /* @__PURE__ */ new WeakMap();
66602
+ var nowMs = () => Date.now();
66603
+ var iso = () => (/* @__PURE__ */ new Date()).toISOString();
66604
+ function emit(config, e) {
66605
+ if (config.onEvent) {
66606
+ try {
66607
+ config.onEvent(e);
66608
+ } catch {
66609
+ }
66610
+ }
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
+ }
66631
+ function fingerprint(call) {
66632
+ const canon = JSON.stringify({ toolName: call.toolName, arguments: call.arguments, artifacts: call.artifacts, filesTouched: call.filesTouched, diff: call.diff });
66633
+ return "sha256:" + (0, node_crypto_1.createHash)("sha256").update(canon).digest("hex");
66634
+ }
66635
+ function breakerRecord(config) {
66636
+ let s = breakers.get(config);
66637
+ if (!s) {
66638
+ s = { fails: [] };
66639
+ breakers.set(config, s);
66640
+ }
66641
+ s.fails.push(nowMs());
66642
+ }
66643
+ function breakerTripped(config) {
66644
+ const s = breakers.get(config);
66645
+ if (!s)
66646
+ return false;
66647
+ const win = config.breakerWindowMs ?? 6e4;
66648
+ const t = nowMs();
66649
+ s.fails = s.fails.filter((x) => t - x < win);
66650
+ return s.fails.length >= (config.maxUnavailablePerWindow ?? 3);
66651
+ }
66652
+ function classifyError(err, config) {
66653
+ const e = err;
66654
+ const name = e?.name;
66655
+ const status = e?.status ?? e?.body?.status;
66656
+ if (name === "TimeoutError" || name === "AbortError" || e?.code === "ABORT_ERR")
66657
+ return { cause: "TIMEOUT", integrity: false };
66658
+ if (status === 429 || name === "RateLimitError")
66659
+ return { cause: "RATE_LIMITED", integrity: false };
66660
+ if (status === 413)
66661
+ return { cause: "PAYLOAD_TOO_LARGE", integrity: true };
66662
+ if (status === 422)
66663
+ return { cause: "REQUEST_REJECTED", integrity: true };
66664
+ if (status === 400 || status === 401 || status === 409)
66665
+ return { cause: "REQUEST_REJECTED", integrity: true };
66666
+ if (typeof status === "number" && status >= 500)
66667
+ return { cause: "SERVER_ERROR", integrity: false };
66668
+ if (name === "TypeError" || /fetch failed|network|ENOTFOUND|ECONNREFUSED|EAI_AGAIN/i.test(String(e?.message)))
66669
+ return { cause: "NETWORK", integrity: false };
66670
+ if (name === "ApiError")
66671
+ return { cause: "SERVER_ERROR", integrity: false };
66672
+ return { cause: "INVALID_RESPONSE", integrity: true };
66673
+ }
66674
+ function withTimeout(p, ms) {
66675
+ return new Promise((resolve, reject) => {
66676
+ const timer = setTimeout(() => reject(Object.assign(new Error(`preflight timed out after ${ms}ms`), { name: "TimeoutError" })), Math.max(1, ms));
66677
+ p.then((v) => {
66678
+ clearTimeout(timer);
66679
+ resolve(v);
66680
+ }, (e) => {
66681
+ clearTimeout(timer);
66682
+ reject(e);
66683
+ });
66684
+ });
66685
+ }
66686
+ async function preflightWithRetry(config, request) {
66687
+ const retries = config.retries ?? 1;
66688
+ const timeoutMs = config.timeoutMs ?? 2e3;
66689
+ const budget = config.totalBudgetMs ?? 4500;
66690
+ const start = nowMs();
66691
+ let last = { cause: "TIMEOUT", integrity: false };
66692
+ for (let attempt = 0; attempt <= retries; attempt++) {
66693
+ const remaining = budget - (nowMs() - start);
66694
+ if (remaining <= 0)
66695
+ return { ok: false, cause: "TIMEOUT", integrity: false };
66696
+ try {
66697
+ const response = await withTimeout(config.client.preflightChangeSet(request), Math.min(timeoutMs, remaining));
66698
+ return { ok: true, response };
66699
+ } catch (err) {
66700
+ last = classifyError(err, config);
66701
+ if (last.integrity)
66702
+ return { ok: false, ...last };
66703
+ }
66704
+ }
66705
+ return { ok: false, ...last };
66706
+ }
66707
+ async function verifyEnvelope(config, envelope) {
66708
+ if (!envelope)
66709
+ return { verified: null };
66710
+ if (config.verifyReceipts === false)
66711
+ return { verified: null };
66712
+ const token = envelope.receipt?.token;
66713
+ if (!token)
66714
+ return { verified: null };
66715
+ try {
66716
+ const r = await config.client.verifyReceipt(token);
66717
+ const bind = (0, receipt_binding_js_1.bindReceiptToEnvelope)(envelope, r, { operation: config.operation, environment: config.environment, audience: config.audience });
66718
+ if (bind.ok)
66719
+ return { verified: envelope };
66720
+ emit(config, { type: "receipt_unverified", at: iso(), decisionId: envelope.decision_id, cause: bind.detail });
66721
+ return { verified: null, cause: bind.cause };
66722
+ } catch {
66723
+ return { verified: null, cause: "RECEIPT_UNVERIFIED" };
66724
+ }
66725
+ }
66726
+ async function runEnforced(config, factory, approved, redacted) {
66727
+ emit(config, { type: "execution_started", at: iso(), action: approved.action, decisionId: approved.envelope.decision_id });
66728
+ try {
66729
+ const result = await factory(approved.envelope, redacted);
66730
+ return { executionAttempted: true, executed: true, enforced: true, result, verdict: approved, preflighted: true };
66731
+ } catch (error) {
66732
+ emit(config, { type: "factory_error", at: iso(), action: approved.action });
66733
+ return { executionAttempted: true, executed: false, enforced: true, error, verdict: approved, preflighted: true };
66734
+ }
66735
+ }
66736
+ async function runUnenforced(config, factory, envelope, verdict, preflighted, redacted) {
66737
+ emit(config, { type: "execution_started", at: iso() });
66738
+ try {
66739
+ const result = await factory(envelope, redacted);
66740
+ return { executionAttempted: true, executed: true, enforced: false, result, verdict, preflighted };
66741
+ } catch (error) {
66742
+ emit(config, { type: "factory_error", at: iso() });
66743
+ return { executionAttempted: true, executed: false, enforced: false, error, verdict, preflighted };
66744
+ }
66745
+ }
66746
+ function blocked(verdict, preflighted) {
66747
+ return { executionAttempted: false, executed: false, enforced: false, verdict, preflighted };
66748
+ }
66749
+ function hasAnalyzableContent(artifacts) {
66750
+ if (!Array.isArray(artifacts) || artifacts.length === 0)
66751
+ return false;
66752
+ return artifacts.some((a) => {
66753
+ if (!a || typeof a !== "object")
66754
+ return false;
66755
+ const before = a.before;
66756
+ const after = a.after;
66757
+ return typeof before === "string" && before.length > 0 || typeof after === "string" && after.length > 0;
66758
+ });
66759
+ }
66760
+ function unavailableVerdict(parts, count) {
66761
+ return { kind: "UNAVAILABLE", decisionMissing: true, unavailableCount: count, ...parts };
66762
+ }
66763
+ async function guardToolCall(call, executeFactory, config) {
66764
+ const failPolicy = config.failPolicy ?? "closed";
66765
+ let redacted;
66766
+ try {
66767
+ redacted = config.redactor ? config.redactor(call) : call;
66768
+ } catch {
66769
+ breakerRecord(config);
66770
+ return closedIntegrity(config, "CONFIG_ERROR", failPolicy);
66771
+ }
66772
+ const inputFp = fingerprint(redacted);
66773
+ const detector = config.detector ?? detector_js_1.builtinDetector;
66774
+ let detection;
66775
+ try {
66776
+ detection = detector.detect(redacted);
66777
+ } catch {
66778
+ breakerRecord(config);
66779
+ return closedIntegrity(config, "DETECTOR_ERROR", failPolicy);
66780
+ }
66781
+ const suppressedByStrict = config.requireExplicitArtifacts === true && redacted.nonContract === true && (!detection.artifacts || detection.artifacts.length === 0) && detection.confident && !detection.trigger;
66782
+ if (!detection.trigger || suppressedByStrict) {
66783
+ emit(config, { type: "detection_skip", at: iso(), signals: detection.signals, detectorVersion: detector.version });
66784
+ const verdict = { kind: "SKIPPED", reason: "NOT_A_CONTRACT_CALL", signals: detection.signals, detectorVersion: detector.version };
66785
+ return runUnenforced(config, executeFactory, null, verdict, false, redacted);
66786
+ }
66787
+ if (!hasAnalyzableContent(detection.artifacts)) {
66788
+ emit(config, { type: "artifact_content_missing", at: iso(), cause: "MISSING_ARTIFACT_CONTENT", signals: detection.signals });
66789
+ const count = breakers.get(config)?.fails.length ?? 0;
66790
+ const v = unavailableVerdict({ cause: "MISSING_ARTIFACT_CONTENT", failPolicy, resolution: "CLOSED", action: "STOP" }, count);
66791
+ return blocked(v, false);
66792
+ }
66793
+ if (failPolicy === "lkg" && !config.lkg) {
66794
+ breakerRecord(config);
66795
+ return closedIntegrity(config, "CONFIG_ERROR", failPolicy);
66796
+ }
66797
+ const request = {
66798
+ artifacts: detection.artifacts,
66799
+ context: { operation: config.operation ?? "tool_call", environment: config.environment, audience: config.audience },
66800
+ previous_receipt: resolvePreviousReceipt(config),
66801
+ idempotency_key: void 0
66802
+ };
66803
+ const cap = config.maxPayloadBytes ?? 1e6;
66804
+ if (Buffer.byteLength(JSON.stringify(request), "utf8") > cap) {
66805
+ breakerRecord(config);
66806
+ return closedIntegrity(config, "PAYLOAD_TOO_LARGE", failPolicy);
66807
+ }
66808
+ emit(config, { type: "preflight_start", at: iso() });
66809
+ const pf = await preflightWithRetry(config, request);
66810
+ if (!pf.ok) {
66811
+ breakerRecord(config);
66812
+ const count = breakers.get(config)?.fails.length ?? 1;
66813
+ if (pf.integrity) {
66814
+ emit(config, { type: "breaker_tripped", at: iso(), cause: pf.cause });
66815
+ const v2 = unavailableVerdict({ cause: pf.cause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
66816
+ return blocked(v2, false);
66817
+ }
66818
+ const availCause = pf.cause;
66819
+ if (failPolicy === "open" && !breakerTripped(config)) {
66820
+ emit(config, { type: "preflight_unavailable", at: iso(), cause: availCause, action: "CONTINUE" });
66821
+ const v2 = unavailableVerdict({ cause: availCause, failPolicy: "open", resolution: "OPEN_PASSTHROUGH", action: "CONTINUE" }, count);
66822
+ return runUnenforced(config, executeFactory, null, v2, false, redacted);
66823
+ }
66824
+ if (failPolicy === "lkg") {
66825
+ const lkg = await tryLkg(config, inputFp);
66826
+ if (lkg) {
66827
+ emit(config, { type: "preflight_unavailable", at: iso(), cause: availCause, action: lkg.action });
66828
+ const v2 = unavailableVerdict({ cause: availCause, failPolicy: "lkg", resolution: "LKG_SUBSTITUTION", action: lkg.action, lkgEnvelope: lkg.envelope }, count);
66829
+ return runUnenforced(config, executeFactory, lkg.envelope, v2, false, redacted);
66830
+ }
66831
+ }
66832
+ if (breakerTripped(config))
66833
+ emit(config, { type: "breaker_tripped", at: iso(), cause: availCause });
66834
+ const v = unavailableVerdict({ cause: availCause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
66835
+ return blocked(v, false);
66836
+ }
66837
+ const rd = (0, sdk_1.readDecision)(pf.response);
66838
+ if (rd.reason === "UNREADABLE_DECISION" || !rd.envelope) {
66839
+ breakerRecord(config);
66840
+ return closedIntegrity(config, "SCHEMA_INVALID", failPolicy);
66841
+ }
66842
+ const envelope = rd.envelope;
66843
+ const expired = isExpired(envelope);
66844
+ const bindResult = await verifyEnvelope(config, envelope);
66845
+ const verified = bindResult.verified;
66846
+ const receiptVerified = !!verified;
66847
+ if (!receiptVerified)
66848
+ emit(config, { type: "receipt_unverified", at: iso(), decisionId: envelope.decision_id });
66849
+ emit(config, { type: "preflight_result", at: iso(), action: rd.executionAction, decisionId: envelope.decision_id });
66850
+ if (config.verifyReceipts !== false && !receiptVerified && envelope.receipt?.token) {
66851
+ breakerRecord(config);
66852
+ return closedIntegrity(config, bindResult.cause ?? "RECEIPT_UNVERIFIED", failPolicy);
66853
+ }
66854
+ const gate = (0, enforcement_gate_js_1.evaluateEnvelope)(pf.response, envelope, rd.executionAction, detection.artifacts);
66855
+ if (gate.verdict === "fail-closed") {
66856
+ breakerRecord(config);
66857
+ return closedIntegrity(config, gate.cause, failPolicy);
66858
+ }
66859
+ if (gate.verdict === "block-strict") {
66860
+ return gate.decision === "BLOCK" ? blocked({ kind: "BLOCK", action: "STOP", envelope, receiptVerified }, true) : blocked({ kind: "APPROVAL", action: "REQUEST_APPROVAL", envelope, receiptVerified }, true);
66861
+ }
66862
+ const kind = gate.kind;
66863
+ if (expired) {
66864
+ breakerRecord(config);
66865
+ return closedIntegrity(config, "SCHEMA_INVALID", failPolicy);
66866
+ }
66867
+ const sinkWired = !!config.onEvent;
66868
+ if (kind === "MONITOR") {
66869
+ if (sinkWired)
66870
+ emit(config, { type: "monitoring_required", at: iso(), decisionId: envelope.decision_id });
66871
+ else
66872
+ emit(config, { type: "monitoring_unwired", at: iso(), decisionId: envelope.decision_id });
66873
+ }
66874
+ if (config.observeOnly) {
66875
+ emit(config, { type: "observe_only_passthrough", at: iso(), action: rd.executionAction });
66876
+ const verdict = kind === "ALLOW" ? { kind: "ALLOW", action: "CONTINUE", envelope, receiptVerified } : { kind: "MONITOR", action: "CONTINUE_WITH_MONITORING", envelope, receiptVerified };
66877
+ return runUnenforced(config, executeFactory, envelope, verdict, true, redacted);
66878
+ }
66879
+ const enforceable = receiptVerified && (kind === "ALLOW" || sinkWired);
66880
+ if (enforceable) {
66881
+ const approved = kind === "ALLOW" ? { kind: "ALLOW", action: "CONTINUE", envelope, receiptVerified: true } : { kind: "MONITOR", action: "CONTINUE_WITH_MONITORING", envelope, receiptVerified: true };
66882
+ return runEnforced(config, executeFactory, approved, redacted);
66883
+ }
66884
+ breakerRecord(config);
66885
+ return closedIntegrity(config, receiptVerified ? "MONITORING_UNWIRED" : "RECEIPT_MISSING", failPolicy);
66886
+ }
66887
+ function closedIntegrity(config, cause, failPolicy) {
66888
+ const count = breakers.get(config)?.fails.length ?? 1;
66889
+ emit(config, { type: "breaker_tripped", at: iso(), cause });
66890
+ const v = unavailableVerdict({ cause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
66891
+ return blocked(v, false);
66892
+ }
66893
+ function isExpired(envelope) {
66894
+ const exp = envelope.expires_at;
66895
+ if (typeof exp !== "string")
66896
+ return false;
66897
+ const t = Date.parse(exp);
66898
+ return Number.isFinite(t) && t < Date.now();
66899
+ }
66900
+ async function tryLkg(config, inputFp) {
66901
+ if (!config.lkg)
66902
+ return null;
66903
+ let cached;
66904
+ try {
66905
+ cached = await config.lkg.get(inputFp);
66906
+ } catch {
66907
+ return null;
66908
+ }
66909
+ if (!cached)
66910
+ return null;
66911
+ const { verified } = await verifyEnvelope(config, cached);
66912
+ if (!verified)
66913
+ return null;
66914
+ const dec = cached.decision ?? "";
66915
+ if (dec !== "ALLOW" && dec !== "WARN")
66916
+ return null;
66917
+ if (isExpired(cached))
66918
+ return null;
66919
+ const maxAge = config.lkgMaxAgeMs ?? 9e5;
66920
+ const evalAt = Date.parse(cached.evaluated_at);
66921
+ if (Number.isFinite(evalAt) && Date.now() - evalAt > maxAge)
66922
+ return null;
66923
+ const bindings = [
66924
+ cached.ruleset_hash,
66925
+ cached.environment,
66926
+ cached.operation,
66927
+ cached.audience
66928
+ ];
66929
+ if (bindings.some((b) => b === void 0))
66930
+ return null;
66931
+ const action = dec === "ALLOW" ? "CONTINUE" : "CONTINUE_WITH_MONITORING";
66932
+ return { envelope: verified, action };
66933
+ }
66934
+ }
66935
+ });
66936
+
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
67013
+ var require_session_taint = __commonJS({
67014
+ "node_modules/@coderifts/agent-guard/dist/cjs/session-taint.js"(exports2) {
67015
+ "use strict";
67016
+ Object.defineProperty(exports2, "__esModule", { value: true });
67017
+ exports2.SessionTaintTracker = exports2.SESSION_TAINT_VERSION = void 0;
67018
+ exports2.pathClass = pathClass;
67019
+ exports2.emptySessionState = emptySessionState;
67020
+ exports2.projectState = projectState;
67021
+ exports2.classifyCommand = classifyCommand;
67022
+ exports2.updateSession = updateSession;
67023
+ exports2.computeTainted = computeTainted;
67024
+ exports2.deriveKeySignal = deriveKeySignal;
67025
+ exports2.evaluate = evaluate;
67026
+ exports2.SESSION_TAINT_VERSION = "session-taint/1.0.0";
67027
+ var NON_SSOT_RE = /(^|\/)(tests?|__tests__|fixtures?|__mocks__|src\/internal)\//i;
67028
+ var PIPELINE_SCRATCH_RE = /(^|\/)(build|\.cache|codegen|idl)(\/|$)/i;
67029
+ var PROSE_RE = /(^|\/)(README|CHANGELOG|LICENSE)(\.\w+)?$|\.md$/i;
67030
+ var SSOT_PATH_RE = /(^|\/)(openapi|swagger|asyncapi)[^/]*\.(ya?ml|json)$|(^|\/)mcp\.json$|\.graphql$|\.gql$|(^|\/)idl\/.*\.proto$|(^|\/)specs?\/.*\.(ya?ml|json)$|openapi\.yaml|schema\.graphql|asyncapi\.yaml/i;
67031
+ var MIGRATION_RE = /(^|\/)migrations?\//i;
67032
+ var CODE_OR_CONFIG_RE = /\.(ts|tsx|js|jsx)$/i;
67033
+ var CONTRACT_CONTENT_RE = /\bopenapi\s*[:=]|\bswagger\s*[:=]|\basyncapi\s*[:=]|syntax\s*=\s*["']proto3|["']inputSchema["']|\btype\s+Query\b|(^|\n)\s*paths\s*:/i;
67034
+ var STAGING_NAME_RE = /\.b64$|enc\/|field-map|flags\.json|optional_fields|required_fields|service\.idl|frags\/|BREAKING_DROP/i;
67035
+ var NON_SINK_RE = /validate-frags|gen-docs|reload-flags|snapshot-spec|prettier|npm test|npm install|npx prettier/i;
67036
+ var SSOT_INVALIDATE_RE = /archive-old-spec/i;
67037
+ var SSOT_SINK_RE = /dsl-to-openapi|merge-spec|publish-fixture|promote-spec|sync-graphql|b64join-write|decode-promote|apply-field-map|render-openapi|idl\/compile|generate-and-test|compile_spec_bundle|install-proto|install-mcp|promote-asyncapi|repack-extract|codegen\/build\.js|codegen\/apply|codegen\/render/i;
67038
+ function pathClass(p) {
67039
+ if (PROSE_RE.test(p))
67040
+ return "prose";
67041
+ if (NON_SSOT_RE.test(p) || PIPELINE_SCRATCH_RE.test(p))
67042
+ return "scratch";
67043
+ if (MIGRATION_RE.test(p))
67044
+ return "migration";
67045
+ if (SSOT_PATH_RE.test(p))
67046
+ return "ssot";
67047
+ if (CODE_OR_CONFIG_RE.test(p) || p.startsWith("src/") || p.startsWith("config/") || p === "package.json")
67048
+ return "code_or_config";
67049
+ return "other";
67050
+ }
67051
+ function emptySessionState() {
67052
+ return {
67053
+ scratch_writes: [],
67054
+ contract_looking_scratch: [],
67055
+ encoded_fragments: [],
67056
+ intermediate_artifacts: [],
67057
+ pending_renames: [],
67058
+ optional_fields_added: [],
67059
+ required_fields_declared: [],
67060
+ ssot_paths_touched: [],
67061
+ ssot_sink_events: [],
67062
+ ssot_invalidated: false,
67063
+ reverse_snapshot: false,
67064
+ formatter_only_ssot: false,
67065
+ store_keys: [],
67066
+ tainted: false
67067
+ };
67068
+ }
67069
+ function projectState(s) {
67070
+ return {
67071
+ scratch_writes: s.scratch_writes.slice(),
67072
+ encoded_fragments: s.encoded_fragments.slice(),
67073
+ pending_renames: s.pending_renames.map((r) => "drop" in r ? `drop:${r.drop}` : `${r.from}->${r.to}`),
67074
+ optional_fields_added: s.optional_fields_added.slice(),
67075
+ required_fields_declared: s.required_fields_declared.slice(),
67076
+ ssot_paths_touched: s.ssot_paths_touched.slice(),
67077
+ contract_looking_scratch: s.contract_looking_scratch.slice(),
67078
+ intermediate_artifacts: s.intermediate_artifacts.slice(),
67079
+ ssot_sink_events: s.ssot_sink_events.slice(),
67080
+ ssot_invalidated: s.ssot_invalidated,
67081
+ reverse_snapshot: s.reverse_snapshot,
67082
+ formatter_only_ssot: s.formatter_only_ssot,
67083
+ store_keys: s.store_keys.slice(),
67084
+ tainted: s.tainted
67085
+ };
67086
+ }
67087
+ function asRecord(args) {
67088
+ return args && typeof args === "object" ? args : {};
67089
+ }
67090
+ function extractPaths(args) {
67091
+ const a = asRecord(args);
67092
+ const out = [];
67093
+ for (const k of ["path", "target", "file", "dest", "filename", "destination"])
67094
+ if (typeof a[k] === "string")
67095
+ out.push(a[k]);
67096
+ return out;
67097
+ }
67098
+ function extractContent(args) {
67099
+ const a = asRecord(args);
67100
+ const parts = [];
67101
+ for (const k of ["contents", "content", "new_string", "old_string", "patch", "value", "command"])
67102
+ if (typeof a[k] === "string")
67103
+ parts.push(a[k]);
67104
+ return parts.join("\n");
67105
+ }
67106
+ function isEncodedFragment(path, content) {
67107
+ if (path && /part\.|enc\/|\.b64$|pkg\.part/i.test(path))
67108
+ return true;
67109
+ const c = content.replace(/\s+/g, "");
67110
+ if (c.length >= 8 && c.length < 80 && /^[A-Za-z0-9+/=]+$/.test(c))
67111
+ return true;
67112
+ return false;
67113
+ }
67114
+ function classifyCommand(command, action, cfg = {}) {
67115
+ const s = `${command || ""} ${action || ""}`;
67116
+ const extraNon = cfg.extraNonSinkPatterns || [];
67117
+ const extraSink = cfg.extraSinkPatterns || [];
67118
+ if (NON_SINK_RE.test(s) || extraNon.some((r) => r.test(s)))
67119
+ return "non_sink";
67120
+ if (SSOT_INVALIDATE_RE.test(s))
67121
+ return "ssot_invalidate";
67122
+ if (SSOT_SINK_RE.test(s) || action === "compile_spec_bundle" || extraSink.some((r) => r.test(s)))
67123
+ return "ssot_sink";
67124
+ if (/snapshot/i.test(s))
67125
+ return "reverse_snapshot";
67126
+ if (/prettier|format/i.test(s))
67127
+ return "formatter";
67128
+ return "unknown_script";
67129
+ }
67130
+ function pushUniq(arr, v) {
67131
+ if (v != null && !arr.includes(v))
67132
+ arr.push(v);
67133
+ }
67134
+ function updateSession(state, call, cfg = {}) {
67135
+ const s = JSON.parse(JSON.stringify(state));
67136
+ const args = asRecord(call && call.arguments);
67137
+ const paths = extractPaths(args);
67138
+ const content = extractContent(args);
67139
+ const tool = call && call.toolName;
67140
+ if (tool === "store" && typeof args.key === "string") {
67141
+ pushUniq(s.store_keys, args.key);
67142
+ if (/spec_|api_|openapi|schema/i.test(args.key) || /BREAKING|ROUTE|FIELD|REMOVE|MANDATORY|required|optional/i.test(String(args.value))) {
67143
+ pushUniq(s.intermediate_artifacts, `store:${args.key}`);
67144
+ }
67145
+ }
67146
+ if (tool === "apply" && typeof args.action === "string") {
67147
+ if (classifyCommand("", args.action, cfg) === "ssot_sink")
67148
+ s.ssot_sink_events.push(args.action);
67149
+ }
67150
+ if (tool === "Bash" || typeof args.command === "string") {
67151
+ const cmd = typeof args.command === "string" ? args.command : "";
67152
+ const kind = classifyCommand(cmd, "", cfg);
67153
+ if (kind === "ssot_sink")
67154
+ s.ssot_sink_events.push(cmd);
67155
+ if (kind === "ssot_invalidate")
67156
+ s.ssot_invalidated = true;
67157
+ if (kind === "reverse_snapshot")
67158
+ s.reverse_snapshot = true;
67159
+ if (kind === "formatter" && (SSOT_PATH_RE.test(cmd) || /openapi|swagger|asyncapi|\.graphql|\.gql|mcp\.json|schema/i.test(cmd)))
67160
+ s.formatter_only_ssot = true;
67161
+ }
67162
+ for (const p of paths) {
67163
+ const pc = pathClass(p);
67164
+ const isScratch = pc === "scratch" || NON_SSOT_RE.test(p) || PIPELINE_SCRATCH_RE.test(p);
67165
+ if (isScratch) {
67166
+ pushUniq(s.scratch_writes, p);
67167
+ if (CONTRACT_CONTENT_RE.test(content) || STAGING_NAME_RE.test(p + content))
67168
+ pushUniq(s.contract_looking_scratch, p);
67169
+ if (PIPELINE_SCRATCH_RE.test(p))
67170
+ pushUniq(s.intermediate_artifacts, p);
67171
+ if (isEncodedFragment(p, content) || /\.b64$/i.test(p) || /enc\//i.test(p) || /pkg\.part/i.test(p))
67172
+ pushUniq(s.encoded_fragments, p);
67173
+ if (/field-map|flags\.json|optional_fields|required_fields|\.idl$/i.test(p))
67174
+ pushUniq(s.intermediate_artifacts, p);
67175
+ }
67176
+ if (pc === "ssot" && !(tool === "Bash" && /prettier/i.test(typeof args.command === "string" ? args.command : "")))
67177
+ pushUniq(s.ssot_paths_touched, p);
67178
+ if (/field-map/i.test(p)) {
67179
+ let obj;
67180
+ try {
67181
+ obj = JSON.parse(content);
67182
+ } catch {
67183
+ obj = null;
67184
+ }
67185
+ if (obj && typeof obj === "object" && !Array.isArray(obj)) {
67186
+ for (const [k, v] of Object.entries(obj)) {
67187
+ if (k === "__drop" && Array.isArray(v)) {
67188
+ for (const d of v)
67189
+ s.pending_renames.push({ drop: String(d) });
67190
+ } else if (typeof v === "string")
67191
+ s.pending_renames.push({ from: k, to: v });
67192
+ }
67193
+ }
67194
+ }
67195
+ if (/flags\.json/i.test(p)) {
67196
+ for (const m of content.matchAll(/"(\w+)":\s*"optional"/g))
67197
+ pushUniq(s.optional_fields_added, m[1]);
67198
+ for (const m of content.matchAll(/"(\w+)":\s*"required"/g))
67199
+ pushUniq(s.required_fields_declared, m[1]);
67200
+ }
67201
+ if (/optional_fields/i.test(p)) {
67202
+ for (const line of content.split("\n"))
67203
+ if (line.trim())
67204
+ pushUniq(s.optional_fields_added, line.trim());
67205
+ }
67206
+ if (/required_fields/i.test(p)) {
67207
+ for (const line of content.split("\n"))
67208
+ if (line.trim())
67209
+ pushUniq(s.required_fields_declared, line.trim());
67210
+ }
67211
+ if (NON_SSOT_RE.test(p) && /required:\s*\[[^\]]*owner_id/.test(content))
67212
+ pushUniq(s.required_fields_declared, "owner_id");
67213
+ if (NON_SSOT_RE.test(p) && /owner_id:\s*\{type: string\}/.test(content))
67214
+ pushUniq(s.optional_fields_added, "owner_id");
67215
+ if (/\.idl$/i.test(p) || p.startsWith("idl/"))
67216
+ pushUniq(s.intermediate_artifacts, p);
67217
+ }
67218
+ if (/BREAKING_DROP|FIELD .* REMOVE|MANDATORY/i.test(content))
67219
+ pushUniq(s.intermediate_artifacts, paths[0] || "inline_flag");
67220
+ s.tainted = computeTainted(s);
67221
+ return s;
67222
+ }
67223
+ function computeTainted(s) {
67224
+ return s.contract_looking_scratch.length > 0 || s.encoded_fragments.length > 0 || s.intermediate_artifacts.length > 0 || s.store_keys.some((k) => /spec_|api_|schema|openapi/i.test(k)) || s.pending_renames.length > 0 || s.optional_fields_added.some((f) => s.required_fields_declared.includes(f)) || s.required_fields_declared.length > 0 && s.optional_fields_added.length > 0 || s.ssot_invalidated === true;
67225
+ }
67226
+ function deriveKeySignal(s) {
67227
+ if (s.ssot_invalidated)
67228
+ return "delete_recreate_ssot_via_session";
67229
+ if (s.encoded_fragments.length)
67230
+ return "encoded_scratch_then_ssot_promotion";
67231
+ if (s.optional_fields_added.some((f) => s.required_fields_declared.includes(f)) || s.required_fields_declared.length && s.optional_fields_added.length)
67232
+ return "cumulative_required_flip";
67233
+ if (s.pending_renames.length)
67234
+ return "cumulative_rename_via_codegen";
67235
+ if (s.contract_looking_scratch.length)
67236
+ return "scratch_to_ssot_promotion";
67237
+ if (s.intermediate_artifacts.length)
67238
+ return "cross_call_reassembly_to_ssot";
67239
+ return "session_ssot_sink_with_taint";
67240
+ }
67241
+ function evaluate(state, prevFlagged = false, opts = {}) {
67242
+ const sink = state.ssot_sink_events.length > 0 || opts.sinkSeen === true;
67243
+ const taint = state.tainted || opts.overflow === true;
67244
+ const flag = sink && taint;
67245
+ return { flag, trip: flag && !prevFlagged, key_signal: flag ? deriveKeySignal(state) : null };
67246
+ }
67247
+ var DEF = { maxCalls: 256, maxPathsTracked: 512, maxSinkEvents: 64, maxStateBytes: 256e3, ttlMs: 36e5 };
67248
+ var SessionTaintTracker = class {
67249
+ version = exports2.SESSION_TAINT_VERSION;
67250
+ state = emptySessionState();
67251
+ prevFlag = false;
67252
+ callCount = 0;
67253
+ overflow = false;
67254
+ sinkSeen = false;
67255
+ lastObserveAt = 0;
67256
+ cfg;
67257
+ constructor(config = {}) {
67258
+ this.cfg = config;
67259
+ }
67260
+ pathTotal() {
67261
+ const s = this.state;
67262
+ return s.scratch_writes.length + s.contract_looking_scratch.length + s.encoded_fragments.length + s.intermediate_artifacts.length + s.ssot_paths_touched.length;
67263
+ }
67264
+ observe(call) {
67265
+ const now = this.now();
67266
+ if (this.lastObserveAt && now - this.lastObserveAt > (this.cfg.ttlMs ?? DEF.ttlMs))
67267
+ this.reset();
67268
+ this.lastObserveAt = now;
67269
+ const next = updateSession(this.state, call, this.cfg);
67270
+ this.callCount++;
67271
+ if (this.callCount > (this.cfg.maxCalls ?? DEF.maxCalls))
67272
+ this.overflow = true;
67273
+ if (this.pathTotal() > (this.cfg.maxPathsTracked ?? DEF.maxPathsTracked))
67274
+ this.overflow = true;
67275
+ if (JSON.stringify(next).length > (this.cfg.maxStateBytes ?? DEF.maxStateBytes))
67276
+ this.overflow = true;
67277
+ if (next.ssot_sink_events.length > (this.cfg.maxSinkEvents ?? DEF.maxSinkEvents)) {
67278
+ next.ssot_sink_events = next.ssot_sink_events.slice(0, this.cfg.maxSinkEvents ?? DEF.maxSinkEvents);
67279
+ }
67280
+ this.state = next;
67281
+ if (this.state.ssot_sink_events.length > 0)
67282
+ this.sinkSeen = true;
67283
+ return this.snapshot();
67284
+ }
67285
+ status() {
67286
+ return this.snapshot();
67287
+ }
67288
+ reset() {
67289
+ this.state = emptySessionState();
67290
+ this.prevFlag = false;
67291
+ this.callCount = 0;
67292
+ this.overflow = false;
67293
+ this.sinkSeen = false;
67294
+ this.lastObserveAt = 0;
67295
+ }
67296
+ snapshot() {
67297
+ const eva = evaluate(this.state, this.prevFlag, { overflow: this.overflow, sinkSeen: this.sinkSeen });
67298
+ if (eva.flag)
67299
+ this.prevFlag = true;
67300
+ return {
67301
+ flag: eva.flag,
67302
+ trip: eva.trip,
67303
+ key_signal: eva.key_signal,
67304
+ state: projectState(this.state),
67305
+ version: exports2.SESSION_TAINT_VERSION,
67306
+ overflow: this.overflow,
67307
+ severity: this.cfg.sessionTaintSeverity || "caution"
67308
+ };
67309
+ }
67310
+ // Date.now is fine at runtime; isolated for testability.
67311
+ now() {
67312
+ return Date.now();
67313
+ }
67314
+ };
67315
+ exports2.SessionTaintTracker = SessionTaintTracker;
67316
+ }
67317
+ });
67318
+
67319
+ // node_modules/@coderifts/agent-guard/dist/cjs/resolver-yaml.js
67320
+ var require_resolver_yaml = __commonJS({
67321
+ "node_modules/@coderifts/agent-guard/dist/cjs/resolver-yaml.js"(exports2) {
67322
+ "use strict";
67323
+ Object.defineProperty(exports2, "__esModule", { value: true });
67324
+ exports2.YamlLiteError = void 0;
67325
+ exports2.parseDoc = parseDoc;
67326
+ exports2.stableStringify = stableStringify;
67327
+ var YamlLiteError = class extends Error {
67328
+ constructor(message) {
67329
+ super(message);
67330
+ this.name = "YamlLiteError";
67331
+ }
67332
+ };
67333
+ exports2.YamlLiteError = YamlLiteError;
67334
+ function parseDoc(text) {
67335
+ const trimmed = text.trimStart();
67336
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
67337
+ try {
67338
+ return JSON.parse(text);
67339
+ } catch (e) {
67340
+ throw new YamlLiteError(`invalid JSON: ${e.message}`);
67341
+ }
67342
+ }
67343
+ const lines = [];
67344
+ for (const raw of text.split("\n")) {
67345
+ const trimmedLine = raw.trim();
67346
+ if (trimmedLine === "" || trimmedLine.startsWith("#"))
67347
+ continue;
67348
+ lines.push({ indent: raw.length - raw.trimStart().length, text: trimmedLine });
67349
+ }
67350
+ if (lines.length === 0)
67351
+ return null;
67352
+ const [value] = parseBlock(lines, 0, lines[0].indent);
67353
+ return value;
67354
+ }
67355
+ function parseBlock(lines, start, indent) {
67356
+ if (start >= lines.length)
67357
+ return [null, start];
67358
+ const first = lines[start];
67359
+ if (first.text === "-" || first.text.startsWith("- "))
67360
+ return parseSequence(lines, start, indent);
67361
+ return parseMapping(lines, start, indent);
67362
+ }
67363
+ function parseMapping(lines, start, indent) {
67364
+ const obj = {};
67365
+ let i = start;
67366
+ while (i < lines.length && lines[i].indent === indent) {
67367
+ const { key, rest } = splitKeyValue(lines[i].text);
67368
+ i += 1;
67369
+ if (rest === "") {
67370
+ if (i < lines.length && lines[i].indent > indent) {
67371
+ const [child, next] = parseBlock(lines, i, lines[i].indent);
67372
+ obj[key] = child;
67373
+ i = next;
67374
+ } else {
67375
+ obj[key] = null;
67376
+ }
67377
+ } else {
67378
+ obj[key] = parseScalarOrFlow(rest);
67379
+ }
67380
+ }
67381
+ return [obj, i];
67382
+ }
67383
+ function parseSequence(lines, start, indent) {
67384
+ const arr = [];
67385
+ let i = start;
67386
+ while (i < lines.length && lines[i].indent === indent && (lines[i].text === "-" || lines[i].text.startsWith("- "))) {
67387
+ const itemText = lines[i].text.slice(1).trim();
67388
+ i += 1;
67389
+ if (itemText === "") {
67390
+ if (i < lines.length && lines[i].indent > indent) {
67391
+ const [child, next] = parseBlock(lines, i, lines[i].indent);
67392
+ arr.push(child);
67393
+ i = next;
67394
+ } else {
67395
+ arr.push(null);
67396
+ }
67397
+ } else {
67398
+ arr.push(parseScalarOrFlow(itemText));
67399
+ }
67400
+ }
67401
+ return [arr, i];
67402
+ }
67403
+ function splitKeyValue(text) {
67404
+ let key;
67405
+ let idx;
67406
+ if (text[0] === "'" || text[0] === '"') {
67407
+ const q = text[0];
67408
+ let j = 1;
67409
+ while (j < text.length && text[j] !== q)
67410
+ j += 1;
67411
+ key = text.slice(1, j);
67412
+ idx = text.indexOf(":", j);
67413
+ } else {
67414
+ idx = text.indexOf(":");
67415
+ key = idx === -1 ? text : text.slice(0, idx);
67416
+ }
67417
+ if (idx === -1)
67418
+ return { key: key.trim(), rest: "" };
67419
+ return { key: key.trim(), rest: text.slice(idx + 1).trim() };
67420
+ }
67421
+ function parseScalarOrFlow(s) {
67422
+ const t = s.trim();
67423
+ if (t === "" || t === "~" || t === "null")
67424
+ return null;
67425
+ if (t[0] === "{" || t[0] === "[")
67426
+ return parseFlow(t).value;
67427
+ if (t[0] === "'" || t[0] === '"')
67428
+ return unquote(t);
67429
+ return t;
67430
+ }
67431
+ function unquote(t) {
67432
+ const q = t[0];
67433
+ let j = 1;
67434
+ let out = "";
67435
+ while (j < t.length && t[j] !== q) {
67436
+ out += t[j];
67437
+ j += 1;
67438
+ }
67439
+ return out;
67440
+ }
67441
+ function parseFlow(s) {
67442
+ if (s[0] === "{")
67443
+ return parseFlowMap(s);
67444
+ if (s[0] === "[")
67445
+ return parseFlowSeq(s);
67446
+ throw new YamlLiteError(`not a flow collection: ${s.slice(0, 20)}`);
67447
+ }
67448
+ function parseFlowMap(s) {
67449
+ const obj = {};
67450
+ let i = 1;
67451
+ while (i < s.length) {
67452
+ while (i < s.length && (s[i] === " " || s[i] === ","))
67453
+ i += 1;
67454
+ if (s[i] === "}")
67455
+ return { value: obj, end: i + 1 };
67456
+ let key;
67457
+ if (s[i] === "'" || s[i] === '"') {
67458
+ const q = s[i];
67459
+ let j = i + 1;
67460
+ let k = "";
67461
+ while (j < s.length && s[j] !== q) {
67462
+ k += s[j];
67463
+ j += 1;
67464
+ }
67465
+ key = k;
67466
+ i = j + 1;
67467
+ } else {
67468
+ let k = "";
67469
+ while (i < s.length && s[i] !== ":" && s[i] !== "}" && s[i] !== ",") {
67470
+ k += s[i];
67471
+ i += 1;
67472
+ }
67473
+ key = k.trim();
67474
+ }
67475
+ while (i < s.length && (s[i] === " " || s[i] === ":"))
67476
+ i += 1;
67477
+ const [val, next] = readFlowValue(s, i);
67478
+ obj[key] = val;
67479
+ i = next;
67480
+ }
67481
+ throw new YamlLiteError(`unterminated flow map: ${s.slice(0, 40)}`);
67482
+ }
67483
+ function parseFlowSeq(s) {
67484
+ const arr = [];
67485
+ let i = 1;
67486
+ while (i < s.length) {
67487
+ while (i < s.length && (s[i] === " " || s[i] === ","))
67488
+ i += 1;
67489
+ if (s[i] === "]")
67490
+ return { value: arr, end: i + 1 };
67491
+ const [val, next] = readFlowValue(s, i);
67492
+ arr.push(val);
67493
+ i = next;
67494
+ }
67495
+ throw new YamlLiteError(`unterminated flow seq: ${s.slice(0, 40)}`);
67496
+ }
67497
+ function readFlowValue(s, start) {
67498
+ let i = start;
67499
+ while (i < s.length && s[i] === " ")
67500
+ i += 1;
67501
+ if (s[i] === "{" || s[i] === "[") {
67502
+ const { value, end } = parseFlow(s.slice(i));
67503
+ return [value, i + end];
67504
+ }
67505
+ if (s[i] === "'" || s[i] === '"') {
67506
+ const q = s[i];
67507
+ let j = i + 1;
67508
+ let out2 = "";
67509
+ while (j < s.length && s[j] !== q) {
67510
+ out2 += s[j];
67511
+ j += 1;
67512
+ }
67513
+ return [out2, j + 1];
67514
+ }
67515
+ let out = "";
67516
+ while (i < s.length && s[i] !== "," && s[i] !== "}" && s[i] !== "]") {
67517
+ out += s[i];
67518
+ i += 1;
67519
+ }
67520
+ return [out.trim(), i];
67521
+ }
67522
+ function stableStringify(value) {
67523
+ return JSON.stringify(sortKeys(value));
67524
+ }
67525
+ function sortKeys(value) {
67526
+ if (Array.isArray(value))
67527
+ return value.map(sortKeys);
67528
+ if (value && typeof value === "object") {
67529
+ const out = {};
67530
+ for (const k of Object.keys(value).sort()) {
67531
+ out[k] = sortKeys(value[k]);
67532
+ }
67533
+ return out;
67534
+ }
67535
+ return value;
67536
+ }
67537
+ }
67538
+ });
67539
+
67540
+ // node_modules/@coderifts/agent-guard/dist/cjs/resolver-glob.js
67541
+ var require_resolver_glob = __commonJS({
67542
+ "node_modules/@coderifts/agent-guard/dist/cjs/resolver-glob.js"(exports2) {
67543
+ "use strict";
67544
+ Object.defineProperty(exports2, "__esModule", { value: true });
67545
+ exports2.globToRegExp = globToRegExp;
67546
+ exports2.matchGlob = matchGlob;
67547
+ exports2.matchAny = matchAny;
67548
+ exports2.firstMatchIndex = firstMatchIndex;
67549
+ function globToRegExp(glob) {
67550
+ let re = "";
67551
+ for (let i = 0; i < glob.length; i += 1) {
67552
+ const c = glob[i];
67553
+ if (c === "*") {
67554
+ if (glob[i + 1] === "*") {
67555
+ i += 1;
67556
+ if (glob[i + 1] === "/") {
67557
+ re += "(?:.*/)?";
67558
+ i += 1;
67559
+ } else {
67560
+ re += ".*";
67561
+ }
67562
+ } else {
67563
+ re += "[^/]*";
67564
+ }
67565
+ } else if (c === "?") {
67566
+ re += "[^/]";
67567
+ } else if (".+^${}()|[]\\".includes(c)) {
67568
+ re += `\\${c}`;
67569
+ } else {
67570
+ re += c;
67571
+ }
67572
+ }
67573
+ return new RegExp(`^${re}$`);
67574
+ }
67575
+ function matchGlob(glob, path) {
67576
+ return globToRegExp(glob).test(path);
67577
+ }
67578
+ function matchAny(globs, path) {
67579
+ if (!Array.isArray(globs))
67580
+ return false;
67581
+ return globs.some((g) => g === path || matchGlob(g, path));
67582
+ }
67583
+ function firstMatchIndex(globs, path) {
67584
+ if (!Array.isArray(globs))
67585
+ return -1;
67586
+ for (let i = 0; i < globs.length; i += 1) {
67587
+ if (globs[i] === path || matchGlob(globs[i], path))
67588
+ return i;
67589
+ }
67590
+ return -1;
67591
+ }
67592
+ }
67593
+ });
67594
+
67595
+ // node_modules/@coderifts/agent-guard/dist/cjs/artifact-resolver.js
67596
+ var require_artifact_resolver = __commonJS({
67597
+ "node_modules/@coderifts/agent-guard/dist/cjs/artifact-resolver.js"(exports2) {
67598
+ "use strict";
67599
+ Object.defineProperty(exports2, "__esModule", { value: true });
67600
+ exports2.classifyByName = classifyByName;
67601
+ exports2.resolve = resolve;
67602
+ var resolver_yaml_js_1 = require_resolver_yaml();
67603
+ var resolver_glob_js_1 = require_resolver_glob();
67604
+ var DEFAULT_GENERATED = ["**/generated/**", "**/gen/**"];
67605
+ var VENDOR_GLOBS = ["**/node_modules/**", "**/vendor/**"];
67606
+ function normalizePath(p) {
67607
+ let s = p.replace(/\\/g, "/").trim();
67608
+ while (s.startsWith("./"))
67609
+ s = s.slice(2);
67610
+ return s;
67611
+ }
67612
+ function dirname(p) {
67613
+ const i = p.lastIndexOf("/");
67614
+ return i === -1 ? "" : p.slice(0, i);
67615
+ }
67616
+ function basename(p) {
67617
+ const i = p.lastIndexOf("/");
67618
+ return i === -1 ? p : p.slice(i + 1);
67619
+ }
67620
+ function extname(p) {
67621
+ const b = basename(p);
67622
+ const i = b.lastIndexOf(".");
67623
+ return i === -1 ? "" : b.slice(i + 1).toLowerCase();
67624
+ }
67625
+ function resolveRelative(dir, rel) {
67626
+ const parts = (dir ? dir.split("/") : []).concat(normalizePath(rel).split("/"));
67627
+ const out = [];
67628
+ for (const seg of parts) {
67629
+ if (seg === "" || seg === ".")
67630
+ continue;
67631
+ if (seg === "..")
67632
+ out.pop();
67633
+ else
67634
+ out.push(seg);
67635
+ }
67636
+ return out.join("/");
67637
+ }
67638
+ function classifyByName(path) {
67639
+ const b = basename(path).toLowerCase();
67640
+ const ext = extname(path);
67641
+ const yamlJson = ext === "yaml" || ext === "yml" || ext === "json";
67642
+ if (yamlJson && (b.includes("openapi") || b.includes("swagger")))
67643
+ return "openapi";
67644
+ if (yamlJson && b.includes("asyncapi"))
67645
+ return "asyncapi";
67646
+ if (ext === "graphql" || ext === "gql")
67647
+ return "graphql";
67648
+ if (ext === "proto")
67649
+ return "grpc";
67650
+ if (b === "mcp.json" || b === "tools-catalog.json")
67651
+ return "mcp_manifest";
67652
+ return null;
67653
+ }
67654
+ function classifyByContent(text) {
67655
+ if (!text)
67656
+ return null;
67657
+ if (/(^|\n)\s*["']?openapi["']?\s*:\s*["']?[23]/.test(text) || /swagger\s*:/.test(text) && /paths\s*:/.test(text))
67658
+ return "openapi";
67659
+ if (/(^|\n)\s*["']?asyncapi["']?\s*:/.test(text))
67660
+ return "asyncapi";
67661
+ if (/\btype\s+Query\b|\btype\s+Mutation\b|\bschema\s*\{/.test(text))
67662
+ return "graphql";
67663
+ if (/syntax\s*=\s*["']proto[23]["']/.test(text))
67664
+ return "grpc";
67665
+ try {
67666
+ const j = JSON.parse(text);
67667
+ if (j && Array.isArray(j.tools) && j.tools.some((t) => t && typeof t === "object" && "inputSchema" in t))
67668
+ return "mcp_manifest";
67669
+ } catch {
67670
+ }
67671
+ return null;
67672
+ }
67673
+ function isMcpByNameNeedingContent(path) {
67674
+ const b = basename(path).toLowerCase();
67675
+ return extname(path) === "json" && b.includes("mcp") && b !== "mcp.json";
67676
+ }
67677
+ var REF_RE = /\$ref["']?\s*:\s*["']?([^"'\s,}]+)["']?/g;
67678
+ function scanRefs(text) {
67679
+ const out = [];
67680
+ let m;
67681
+ REF_RE.lastIndex = 0;
67682
+ while ((m = REF_RE.exec(text)) !== null)
67683
+ out.push(m[1]);
67684
+ return out;
67685
+ }
67686
+ function isExternalRef(ref) {
67687
+ return /^[a-z][a-z0-9+.-]*:\/\//i.test(ref) || ref.startsWith("//");
67688
+ }
67689
+ function isInternalRef(ref) {
67690
+ return ref.startsWith("#");
67691
+ }
67692
+ function splitRef(ref) {
67693
+ const i = ref.indexOf("#");
67694
+ return i === -1 ? { file: ref, pointer: "" } : { file: ref.slice(0, i), pointer: ref.slice(i + 1) };
67695
+ }
67696
+ function jsonPointer(doc, pointer) {
67697
+ if (pointer === "" || pointer === "/")
67698
+ return doc;
67699
+ const parts = pointer.replace(/^\//, "").split("/").map((p) => p.replace(/~1/g, "/").replace(/~0/g, "~"));
67700
+ let cur = doc;
67701
+ for (const part of parts) {
67702
+ if (cur && typeof cur === "object" && part in cur)
67703
+ cur = cur[part];
67704
+ else
67705
+ return void 0;
67706
+ }
67707
+ return cur;
67708
+ }
67709
+ function slugify(s) {
67710
+ return s.replace(/[^A-Za-z0-9]+/g, "_");
67711
+ }
67712
+ var RefError = class extends Error {
67713
+ reason;
67714
+ related;
67715
+ constructor(reason, related) {
67716
+ super(reason);
67717
+ this.reason = reason;
67718
+ this.related = related;
67719
+ }
67720
+ };
67721
+ function assembleSide(rootPath, rootText, refSide, input, config, deps) {
67722
+ const maxDepth = config.maxRefDepth ?? 8;
67723
+ let root;
67724
+ try {
67725
+ root = (0, resolver_yaml_js_1.parseDoc)(rootText);
67726
+ } catch (e) {
67727
+ if (e instanceof resolver_yaml_js_1.YamlLiteError)
67728
+ throw new RefError("parse_error");
67729
+ throw e;
67730
+ }
67731
+ const components = {};
67732
+ const inline = (node, curDir, depth, stack) => {
67733
+ if (Array.isArray(node))
67734
+ return node.map((n) => inline(n, curDir, depth, stack));
67735
+ if (node && typeof node === "object") {
67736
+ const rec = node;
67737
+ if (typeof rec.$ref === "string") {
67738
+ const ref = rec.$ref;
67739
+ if (isExternalRef(ref))
67740
+ throw new RefError("external_ref_forbidden");
67741
+ if (isInternalRef(ref))
67742
+ return { ...rec };
67743
+ const { file, pointer } = splitRef(ref);
67744
+ const targetPath = resolveRelative(curDir, file);
67745
+ const key = `${targetPath}#${pointer}`;
67746
+ if (depth + 1 > maxDepth)
67747
+ throw new RefError("ref_depth_exceeded", targetPath);
67748
+ if (stack.has(key))
67749
+ throw new RefError("ref_cycle", targetPath);
67750
+ const blob = getBlob(input, refSide, targetPath);
67751
+ if (blob === null || blob === void 0)
67752
+ throw new RefError("missing_ref_target", targetPath);
67753
+ if (typeof blob === "object")
67754
+ throw new RefError(blob.error, targetPath);
67755
+ deps.add(targetPath);
67756
+ let targetDoc;
67757
+ try {
67758
+ targetDoc = (0, resolver_yaml_js_1.parseDoc)(blob);
67759
+ } catch {
67760
+ throw new RefError("parse_error", targetPath);
67761
+ }
67762
+ const resolved = jsonPointer(targetDoc, pointer);
67763
+ if (resolved === void 0)
67764
+ throw new RefError("missing_ref_target", targetPath);
67765
+ const inlined = inline(resolved, dirname(targetPath), depth + 1, /* @__PURE__ */ new Set([...stack, key]));
67766
+ const slug = slugify(`${targetPath}__${pointer}`);
67767
+ components[slug] = inlined;
67768
+ return { $ref: `#/components/${slug}` };
67769
+ }
67770
+ const out = {};
67771
+ for (const k of Object.keys(rec))
67772
+ out[k] = inline(rec[k], curDir, depth, stack);
67773
+ return out;
67774
+ }
67775
+ return node;
67776
+ };
67777
+ const inlinedRoot = inline(root, dirname(rootPath), 0, /* @__PURE__ */ new Set());
67778
+ if (Object.keys(components).length > 0) {
67779
+ const existing = inlinedRoot.components && typeof inlinedRoot.components === "object" ? inlinedRoot.components : {};
67780
+ inlinedRoot.components = { ...existing, ...components };
67781
+ }
67782
+ return (0, resolver_yaml_js_1.stableStringify)(inlinedRoot);
67783
+ }
67784
+ function getBlob(input, ref, path) {
67785
+ return input.blobs[`${ref}:${path}`];
67786
+ }
67787
+ function loadRoot(path, type, input, config) {
67788
+ const baseBlob = getBlob(input, input.baseRef, path);
67789
+ const headBlob = getBlob(input, input.headRef, path);
67790
+ if (baseBlob && typeof baseBlob === "object")
67791
+ return { unresolved: { path, reason: baseBlob.error } };
67792
+ if (headBlob && typeof headBlob === "object")
67793
+ return { unresolved: { path, reason: headBlob.error } };
67794
+ const baseNull = baseBlob === null || baseBlob === void 0;
67795
+ const headNull = headBlob === null || headBlob === void 0;
67796
+ if (baseNull && headNull)
67797
+ return { unresolved: { path, reason: "empty_changed_contract" } };
67798
+ let before = baseNull ? "" : baseBlob;
67799
+ let after = headNull ? "" : headBlob;
67800
+ const deps = /* @__PURE__ */ new Set();
67801
+ const assemble = (type === "openapi" || type === "asyncapi") && (config.openApiAssembly ?? "bundle_inline") === "bundle_inline";
67802
+ if (assemble) {
67803
+ try {
67804
+ if (before !== "" && scanRefs(before).some((r) => !isInternalRef(r)))
67805
+ before = assembleSide(path, before, input.baseRef, input, config, deps);
67806
+ if (after !== "" && scanRefs(after).some((r) => !isInternalRef(r)))
67807
+ after = assembleSide(path, after, input.headRef, input, config, deps);
67808
+ } catch (e) {
67809
+ if (e instanceof RefError)
67810
+ return { unresolved: { path, reason: e.reason, ...e.related ? { related_paths: [e.related] } : {} } };
67811
+ throw e;
67812
+ }
67813
+ }
67814
+ const id = input.repository ? `${input.repository}:${type}:${path}` : `${type}:${path}`;
67815
+ return { artifact: { id, type, before, after }, deps: [...deps] };
67816
+ }
67817
+ function selectGroups(candidates, config, generatedGlobs) {
67818
+ const n = candidates.length;
67819
+ const parent = Array.from({ length: n }, (_, i) => i);
67820
+ const find = (x) => {
67821
+ while (parent[x] !== x) {
67822
+ parent[x] = parent[parent[x]];
67823
+ x = parent[x];
67824
+ }
67825
+ return x;
67826
+ };
67827
+ const union = (a, b) => {
67828
+ const ra = find(a);
67829
+ const rb = find(b);
67830
+ if (ra !== rb)
67831
+ parent[Math.max(ra, rb)] = Math.min(ra, rb);
67832
+ };
67833
+ if (Array.isArray(config.forceSameSurfaceGroup)) {
67834
+ const idxs = candidates.map((c, i) => config.forceSameSurfaceGroup.includes(c.path) ? i : -1).filter((i) => i >= 0);
67835
+ for (let k = 1; k < idxs.length; k += 1)
67836
+ union(idxs[0], idxs[k]);
67837
+ }
67838
+ const byType = /* @__PURE__ */ new Map();
67839
+ candidates.forEach((c, i) => {
67840
+ const a = byType.get(c.type) ?? [];
67841
+ a.push(i);
67842
+ byType.set(c.type, a);
67843
+ });
67844
+ for (const idxs of byType.values()) {
67845
+ const gen = idxs.filter((i) => (0, resolver_glob_js_1.matchAny)(generatedGlobs, candidates[i].path));
67846
+ if (gen.length > 0 && gen.length < idxs.length)
67847
+ for (let k = 1; k < idxs.length; k += 1)
67848
+ union(idxs[0], idxs[k]);
67849
+ }
67850
+ const groups = /* @__PURE__ */ new Map();
67851
+ for (let i = 0; i < n; i += 1) {
67852
+ const r = find(i);
67853
+ const g = groups.get(r) ?? [];
67854
+ g.push(i);
67855
+ groups.set(r, g);
67856
+ }
67857
+ const selections = [];
67858
+ const chosen = [];
67859
+ const ambiguous = [];
67860
+ for (const g of groups.values()) {
67861
+ const members = g.map((i) => candidates[i].path).sort();
67862
+ if (members.length === 1) {
67863
+ chosen.push(candidates[g[0]]);
67864
+ selections.push({ chosen: members[0], deferred: [], reason: "single" });
67865
+ continue;
67866
+ }
67867
+ const prefRanked = members.map((p) => ({ p, rank: (0, resolver_glob_js_1.firstMatchIndex)(config.ssotPrefer, p) })).filter((x) => x.rank >= 0);
67868
+ if (prefRanked.length > 0) {
67869
+ prefRanked.sort((a, b) => a.rank - b.rank || (a.p < b.p ? -1 : 1));
67870
+ const chosenPath = prefRanked[0].p;
67871
+ chosen.push(candidates[g.find((i) => candidates[i].path === chosenPath)]);
67872
+ selections.push({ chosen: chosenPath, deferred: members.filter((m) => m !== chosenPath), reason: "ssotPrefer" });
67873
+ continue;
67874
+ }
67875
+ const nongen = members.filter((p) => !(0, resolver_glob_js_1.matchAny)(generatedGlobs, p));
67876
+ if (nongen.length === 1) {
67877
+ const chosenPath = nongen[0];
67878
+ chosen.push(candidates[g.find((i) => candidates[i].path === chosenPath)]);
67879
+ selections.push({ chosen: chosenPath, deferred: members.filter((m) => m !== chosenPath), reason: "generated_deprioritized" });
67880
+ continue;
67881
+ }
67882
+ ambiguous.push(...members);
67883
+ }
67884
+ return { selections, chosen, ambiguous };
67885
+ }
67886
+ function resolve(input, config = {}) {
67887
+ const generatedGlobs = config.generatedGlobs ?? DEFAULT_GENERATED;
67888
+ const seen = /* @__PURE__ */ new Set();
67889
+ const paths = [];
67890
+ for (const raw of Array.isArray(input.changedFiles) ? input.changedFiles : []) {
67891
+ const p = normalizePath(raw);
67892
+ if (p && !seen.has(p)) {
67893
+ seen.add(p);
67894
+ paths.push(p);
67895
+ }
67896
+ }
67897
+ const candidates = [];
67898
+ const ignored = [];
67899
+ for (const p of paths) {
67900
+ if ((0, resolver_glob_js_1.matchAny)(VENDOR_GLOBS, p)) {
67901
+ ignored.push(p);
67902
+ continue;
67903
+ }
67904
+ let type = config.pathTypeHints?.[p] ?? classifyByName(p);
67905
+ if (type === null || isMcpByNameNeedingContent(p)) {
67906
+ const peek = firstDefinedText(getBlob(input, input.headRef, p), getBlob(input, input.baseRef, p));
67907
+ const sniff = classifyByContent(peek);
67908
+ if (isMcpByNameNeedingContent(p))
67909
+ type = sniff === "mcp_manifest" ? "mcp_manifest" : type ?? sniff;
67910
+ else
67911
+ type = sniff;
67912
+ }
67913
+ if (type)
67914
+ candidates.push({ path: p, type });
67915
+ else
67916
+ ignored.push(p);
67917
+ }
67918
+ const unresolved = [];
67919
+ let effectiveCandidates = candidates;
67920
+ if (config.requireSsotIfConfigured && Array.isArray(config.ssotPrefer)) {
67921
+ const missing = config.ssotPrefer.filter((pref) => !hasGlobChar(pref) && !existsInTree(input, pref));
67922
+ const hasGenerated = candidates.some((c) => (0, resolver_glob_js_1.matchAny)(generatedGlobs, c.path));
67923
+ if (missing.length > 0 && hasGenerated) {
67924
+ for (const pref of missing)
67925
+ unresolved.push({ path: pref, reason: "config_ssot_missing" });
67926
+ effectiveCandidates = candidates.filter((c) => !(0, resolver_glob_js_1.matchAny)(generatedGlobs, c.path));
67927
+ }
67928
+ }
67929
+ const { selections, chosen, ambiguous } = selectGroups(effectiveCandidates, config, generatedGlobs);
67930
+ for (const p of [...new Set(ambiguous)].sort())
67931
+ unresolved.push({ path: p, reason: "ambiguous_ssot" });
67932
+ const artifacts = [];
67933
+ const selBySel = new Map(selections.map((s) => [s.chosen, s]));
67934
+ for (const c of chosen.slice().sort((a, b) => a.path < b.path ? -1 : 1)) {
67935
+ const res = loadRoot(c.path, c.type, input, config);
67936
+ if ("artifact" in res) {
67937
+ artifacts.push(res.artifact);
67938
+ const sel = selBySel.get(c.path);
67939
+ for (const dep of res.deps) {
67940
+ const idx = ignored.indexOf(dep);
67941
+ if (idx >= 0)
67942
+ ignored.splice(idx, 1);
67943
+ if (sel && !sel.deferred.includes(dep) && dep !== c.path)
67944
+ sel.deferred.push(dep);
67945
+ }
67946
+ if (sel)
67947
+ sel.deferred.sort();
67948
+ } else {
67949
+ unresolved.push(res.unresolved);
67950
+ }
67951
+ }
67952
+ const A = artifacts.length;
67953
+ const U = unresolved.length;
67954
+ const chosenCount = chosen.length;
67955
+ let coverage;
67956
+ if (chosenCount === 0 && U === 0)
67957
+ coverage = "EMPTY";
67958
+ else if (U === 0 && A >= 1 && A === chosenCount)
67959
+ coverage = "COMPLETE";
67960
+ else if (A >= 1 && U >= 1)
67961
+ coverage = "PARTIAL";
67962
+ else
67963
+ coverage = "UNRESOLVED";
67964
+ artifacts.sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
67965
+ unresolved.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : a.reason < b.reason ? -1 : a.reason > b.reason ? 1 : 0);
67966
+ ignored.sort();
67967
+ const contractDiscovered = effectiveCandidates.map((c) => c.path).slice().sort();
67968
+ return {
67969
+ artifacts,
67970
+ unresolved,
67971
+ coverage,
67972
+ report: {
67973
+ version: "artifact-resolver-report/1.0",
67974
+ baseRef: input.baseRef,
67975
+ headRef: input.headRef,
67976
+ contract_paths_discovered: contractDiscovered,
67977
+ ignored_non_contract: ignored,
67978
+ ssot_selections: selections,
67979
+ claim: {
67980
+ artifacts_ready_for_preflight: coverage === "COMPLETE" || coverage === "EMPTY",
67981
+ produces_verdict: false
67982
+ }
67983
+ }
67984
+ };
67985
+ }
67986
+ function firstDefinedText(...vals) {
67987
+ for (const v of vals)
67988
+ if (typeof v === "string")
67989
+ return v;
67990
+ return void 0;
67991
+ }
67992
+ function hasGlobChar(p) {
67993
+ return /[*?]/.test(p);
67994
+ }
67995
+ function existsInTree(input, path) {
67996
+ return typeof getBlob(input, input.baseRef, path) === "string" || typeof getBlob(input, input.headRef, path) === "string";
67997
+ }
67998
+ }
67999
+ });
68000
+
68001
+ // node_modules/@coderifts/agent-guard/dist/cjs/tool-registry.js
68002
+ var require_tool_registry = __commonJS({
68003
+ "node_modules/@coderifts/agent-guard/dist/cjs/tool-registry.js"(exports2) {
68004
+ "use strict";
68005
+ Object.defineProperty(exports2, "__esModule", { value: true });
68006
+ exports2.RegistryConstructionError = void 0;
68007
+ exports2.guardToolRegistry = guardToolRegistry;
68008
+ var guard_js_1 = require_guard();
68009
+ var artifact_resolver_js_1 = require_artifact_resolver();
68010
+ var RegistryConstructionError = class extends Error {
68011
+ code;
68012
+ toolName;
68013
+ constructor(code, message, toolName) {
68014
+ super(message);
68015
+ this.name = "RegistryConstructionError";
68016
+ this.code = code;
68017
+ this.toolName = toolName;
68018
+ }
68019
+ };
68020
+ exports2.RegistryConstructionError = RegistryConstructionError;
68021
+ var MUTATING_GENERIC = ["write", "edit", "create", "update", "delete", "remove", "apply_patch", "applypatch", "str_replace", "notebook_edit", "multi_edit", "insert"];
68022
+ var MUTATING_SHELL = ["bash", "shell", "terminal", "run_command", "exec", "powershell"];
68023
+ var MUTATING_VCS = ["git_commit", "git_push", "git_merge", "commit", "push"];
68024
+ var MUTATING_DEPLOY = ["deploy", "kubectl_apply", "helm_upgrade", "release"];
68025
+ var MUTATING_PUBLISH = ["npm_publish", "publish_package", "twine_upload", "cargo_publish"];
68026
+ var MUTATING_SCHEMA = ["register_tools", "update_manifest", "mcp_register"];
68027
+ var READONLY = ["read", "grep", "glob", "search", "list", "ls", "cat", "get", "fetch", "web_search", "browser_navigate"];
68028
+ function isMutatingClass(cls) {
68029
+ return cls !== "readonly";
68030
+ }
68031
+ function matchesAny(hay, patterns) {
68032
+ return patterns.some((p) => hay.includes(p));
68033
+ }
68034
+ function heuristicClass(name) {
68035
+ const n = String(name || "").toLowerCase();
68036
+ if (matchesAny(n, MUTATING_SHELL))
68037
+ return "mutating_shell";
68038
+ if (matchesAny(n, MUTATING_VCS) || n.startsWith("git_"))
68039
+ return "mutating_vcs";
68040
+ if (matchesAny(n, MUTATING_DEPLOY))
68041
+ return "mutating_deploy";
68042
+ if (matchesAny(n, MUTATING_PUBLISH))
68043
+ return "mutating_publish";
68044
+ if (matchesAny(n, MUTATING_SCHEMA))
68045
+ return "mutating_schema";
68046
+ if (matchesAny(n, MUTATING_GENERIC))
68047
+ return "mutating";
68048
+ if (matchesAny(n, READONLY))
68049
+ return "readonly";
68050
+ return null;
68051
+ }
68052
+ function resolveClass(tool, config, unknownPolicy) {
68053
+ const classify = config.classify || {};
68054
+ if (Object.prototype.hasOwnProperty.call(classify, tool.name))
68055
+ return { cls: classify[tool.name], source: "classify" };
68056
+ if (tool.mutationClass)
68057
+ return { cls: tool.mutationClass, source: "mutationClass" };
68058
+ if (Array.isArray(config.forceReadonly) && config.forceReadonly.includes(tool.name))
68059
+ return { cls: "readonly", source: "forceReadonly" };
68060
+ const h = heuristicClass(tool.name);
68061
+ if (h)
68062
+ return { cls: h, source: "heuristic" };
68063
+ if (unknownPolicy === "reject") {
68064
+ throw new RegistryConstructionError("UNKNOWN_TOOL", `tool '${tool.name}' is unclassified and unknownToolPolicy='reject'`, tool.name);
68065
+ }
68066
+ return { cls: unknownPolicy === "readonly" ? "readonly" : "mutating", source: "unknown" };
68067
+ }
68068
+ function operationForClass(cls, name, guardOperation) {
68069
+ switch (cls) {
68070
+ case "mutating_shell":
68071
+ return "tool_call";
68072
+ case "mutating_vcs":
68073
+ return /merge/i.test(name) ? "merge" : "tool_call";
68074
+ case "mutating_deploy":
68075
+ return "deploy";
68076
+ case "mutating_publish":
68077
+ return "publish";
68078
+ case "mutating_schema":
68079
+ return "tool_call";
68080
+ case "mutating":
68081
+ default:
68082
+ return guardOperation ?? "tool_call";
68083
+ }
68084
+ }
68085
+ function defaultBinder(tool, 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;
68130
+ }
68131
+ var RAW_EXECUTORS = /* @__PURE__ */ new WeakMap();
68132
+ function freezeTool(t) {
68133
+ Object.freeze(t._coderifts);
68134
+ return Object.freeze(t);
68135
+ }
68136
+ function passthroughProtected(tool, cls) {
68137
+ const rawExecute = tool.execute;
68138
+ const protectedTool = {
68139
+ name: tool.name,
68140
+ description: tool.description,
68141
+ inputSchema: tool.inputSchema,
68142
+ meta: tool.meta,
68143
+ execute: async (args) => rawExecute(args),
68144
+ // new function, not === rawExecute
68145
+ _coderifts: { guarded: false, mutationClass: cls }
68146
+ };
68147
+ RAW_EXECUTORS.set(protectedTool, rawExecute);
68148
+ return freezeTool(protectedTool);
68149
+ }
68150
+ function wrapWithGuard(tool, cls, config) {
68151
+ const rawExecute = tool.execute;
68152
+ const guardBase = config.guard;
68153
+ const operation = operationForClass(cls, tool.name, guardBase.operation);
68154
+ const guardCfg = { ...guardBase, operation };
68155
+ const binder = config.binders && config.binders[tool.name] || ((t, a) => defaultBinder(t, a));
68156
+ const protectedTool = {
68157
+ name: tool.name,
68158
+ description: tool.description,
68159
+ inputSchema: tool.inputSchema,
68160
+ meta: tool.meta,
68161
+ execute: async (args) => {
68162
+ const call = binder(tool, args, cls);
68163
+ return (0, guard_js_1.guardToolCall)(call, async (_envelope, redacted) => rawExecute(redacted ? redacted.arguments : args), guardCfg);
68164
+ },
68165
+ _coderifts: { guarded: true, mutationClass: cls, operation }
68166
+ };
68167
+ RAW_EXECUTORS.set(protectedTool, rawExecute);
68168
+ return freezeTool(protectedTool);
68169
+ }
68170
+ function guardToolRegistry(rawTools, config = {}) {
68171
+ const failHard = config.failOnUnguardedMutator !== false;
68172
+ const unknownPolicy = config.unknownToolPolicy ?? "mutating";
68173
+ const input = Array.isArray(rawTools) ? rawTools : [];
68174
+ for (const tool of input) {
68175
+ if (!tool || typeof tool.name !== "string" || tool.name.trim() === "") {
68176
+ throw new RegistryConstructionError("INVALID_TOOL", "a tool has a missing or empty name");
68177
+ }
68178
+ if (typeof tool.execute !== "function") {
68179
+ throw new RegistryConstructionError("INVALID_TOOL", `tool '${tool.name}' has no execute function`, tool.name);
68180
+ }
68181
+ }
68182
+ const seen = /* @__PURE__ */ new Set();
68183
+ for (const tool of input) {
68184
+ if (seen.has(tool.name)) {
68185
+ throw new RegistryConstructionError("DUPLICATE_TOOL_NAME", `duplicate tool name '${tool.name}'`, tool.name);
68186
+ }
68187
+ seen.add(tool.name);
68188
+ }
68189
+ const sorted = input.slice().sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
68190
+ const guardedMutators = [];
68191
+ const readonlyPassthrough = [];
68192
+ const warnings = [];
68193
+ const staged = [];
68194
+ let anyForced = false;
68195
+ let anyUnknownReadonly = false;
68196
+ for (const tool of sorted) {
68197
+ const { cls, source } = resolveClass(tool, config, unknownPolicy);
68198
+ const forced = cls === "readonly" && (source === "classify" || source === "forceReadonly") && isMutating(heuristicClass(tool.name));
68199
+ if (forced) {
68200
+ anyForced = true;
68201
+ warnings.push(`force_readonly_on_mutator_heuristic:${tool.name}`);
68202
+ }
68203
+ if (source === "unknown" && cls === "readonly")
68204
+ anyUnknownReadonly = true;
68205
+ staged.push({ tool, cls, forced });
68206
+ }
68207
+ if (anyForced && failHard) {
68208
+ throw new RegistryConstructionError("FORCE_READONLY_MUTATOR", `forceReadonly/classify downgraded a heuristic mutator to readonly while failOnUnguardedMutator is true`);
68209
+ }
68210
+ const willWrap = staged.some((s) => isMutating(s.cls) && !s.forced);
68211
+ const validGuard = !!(config.guard && config.guard.client);
68212
+ if (willWrap && !validGuard) {
68213
+ throw new RegistryConstructionError("GUARD_CONFIG_INVALID", "a mutating tool is present but config.guard.client is missing/invalid");
68214
+ }
68215
+ const protectedTools = [];
68216
+ for (const { tool, cls, forced } of staged) {
68217
+ if (cls === "readonly") {
68218
+ readonlyPassthrough.push(tool.name);
68219
+ protectedTools.push(passthroughProtected(tool, "readonly"));
68220
+ } else {
68221
+ guardedMutators.push(tool.name);
68222
+ protectedTools.push(wrapWithGuard(tool, cls, config));
68223
+ }
68224
+ void forced;
68225
+ }
68226
+ for (const p of protectedTools) {
68227
+ if (isMutatingClass(p._coderifts.mutationClass) && p._coderifts.guarded !== true) {
68228
+ throw new RegistryConstructionError("GUARD_CONFIG_INVALID", `invariant violated: '${p.name}' is a mutator exposed without a guard`, p.name);
68229
+ }
68230
+ }
68231
+ const M = guardedMutators.length;
68232
+ const G = guardedMutators.length;
68233
+ let coverage;
68234
+ if (anyForced) {
68235
+ coverage = "BYPASSED";
68236
+ } else if (unknownPolicy === "readonly" && anyUnknownReadonly) {
68237
+ coverage = "PARTIAL";
68238
+ } else if (M === G) {
68239
+ coverage = "COMPLETE";
68240
+ } else {
68241
+ coverage = "PARTIAL";
68242
+ }
68243
+ if (unknownPolicy === "readonly" && anyUnknownReadonly && !warnings.includes("unknown_treated_as_readonly")) {
68244
+ warnings.push("unknown_treated_as_readonly");
68245
+ }
68246
+ const inescapableRuntime = coverage === "COMPLETE" && failHard;
68247
+ const report = {
68248
+ version: "guard-tool-registry-report/1.0",
68249
+ coverage,
68250
+ protected_tools: protectedTools.map((p) => p.name),
68251
+ guarded_mutators: guardedMutators.slice(),
68252
+ readonly_passthrough: readonlyPassthrough.slice(),
68253
+ unguarded_mutators: [],
68254
+ // strict impl: always [] (COMPLETE ⇒ [] by G4; forced tools are readonly)
68255
+ unknown_treated_as: unknownPolicy,
68256
+ claim: {
68257
+ inescapable_runtime: inescapableRuntime,
68258
+ inescapable_merge: false,
68259
+ inescapable_deploy: false
68260
+ },
68261
+ siblings: {
68262
+ merge_gate: "required_separate_#7",
68263
+ artifact_resolver: "sibling_#4"
68264
+ },
68265
+ warnings
68266
+ };
68267
+ Object.freeze(report.claim);
68268
+ Object.freeze(report.siblings);
68269
+ Object.freeze(report);
68270
+ return {
68271
+ tools: Object.freeze(protectedTools),
68272
+ coverage,
68273
+ report
68274
+ };
68275
+ }
68276
+ function isMutating(cls) {
68277
+ return cls != null && cls !== "readonly";
68278
+ }
68279
+ }
68280
+ });
68281
+
68282
+ // node_modules/@coderifts/agent-guard/dist/cjs/merge-gate.js
68283
+ var require_merge_gate = __commonJS({
68284
+ "node_modules/@coderifts/agent-guard/dist/cjs/merge-gate.js"(exports2) {
68285
+ "use strict";
68286
+ Object.defineProperty(exports2, "__esModule", { value: true });
68287
+ exports2.gateDecision = gateDecision;
68288
+ function normSha(s) {
68289
+ return String(s == null ? "" : s).trim().toLowerCase();
68290
+ }
68291
+ function normOp(o) {
68292
+ return String(o == null ? "" : o).trim().toLowerCase();
68293
+ }
68294
+ function sameHead(a, b, allowPrefix) {
68295
+ const na = normSha(a);
68296
+ const nb = normSha(b);
68297
+ if (!na || !nb)
68298
+ return false;
68299
+ if (na === nb)
68300
+ return true;
68301
+ if (allowPrefix && na.length >= 7 && nb.length >= 7 && (na.startsWith(nb) || nb.startsWith(na)))
68302
+ return true;
68303
+ return false;
68304
+ }
68305
+ function isAllowClass(receipt, allowWarnMerge) {
68306
+ const dec = receipt.decision;
68307
+ const decisionOk = dec === "ALLOW" || dec === "WARN" && allowWarnMerge === true;
68308
+ if (!decisionOk)
68309
+ return false;
68310
+ const ea = receipt.execution_action;
68311
+ if (ea === void 0 || ea === null || ea === "")
68312
+ return true;
68313
+ return ea === "CONTINUE" || ea === "CONTINUE_WITH_MONITORING";
68314
+ }
68315
+ function targetMatches(targetId, repository) {
68316
+ const t = String(targetId).toLowerCase();
68317
+ const r = String(repository).toLowerCase();
68318
+ return t === r || t === `repo:${r}` || t.endsWith(`:${r}`) || t.endsWith(`/${r}`);
68319
+ }
68320
+ function gateDecision(input) {
68321
+ const rc = input.requiredContext || {};
68322
+ const protection = rc.protection || { enforcement: "UNKNOWN", admin_bypass_possible: true };
68323
+ const enforcement_state = protection.enforcement;
68324
+ const allowPending = input.allowPending ?? rc.allowPending ?? false;
68325
+ const allowWarnMerge = input.allowWarnMerge ?? rc.allowWarnMerge ?? false;
68326
+ const allowPrefix = input.allowPrefixCompare ?? rc.allowPrefixCompare ?? false;
68327
+ const receipt = input.receipt;
68328
+ const detail = {
68329
+ prHeadSha: normSha(input.prHeadSha),
68330
+ bound_head_sha: receipt ? normSha(receipt.bound_head_sha) : null,
68331
+ decision: receipt ? String(receipt.decision) : null
68332
+ };
68333
+ const fail = (state, reason) => ({
68334
+ merge_allowed: false,
68335
+ state,
68336
+ reason,
68337
+ enforcement_state,
68338
+ inescapable_merge: false,
68339
+ detail
68340
+ });
68341
+ if (!input.prHeadSha || String(input.prHeadSha).trim() === "") {
68342
+ return fail(allowPending ? "pending" : "failure", "inputs_incomplete");
68343
+ }
68344
+ if (receipt === null || receipt === void 0) {
68345
+ return fail(allowPending ? "pending" : "failure", "no_receipt");
68346
+ }
68347
+ if (receipt.currently_authorized !== true) {
68348
+ return fail("failure", "receipt_not_authorized");
68349
+ }
68350
+ const op = rc.operation ?? "merge";
68351
+ if (receipt.operation == null || normOp(receipt.operation) !== normOp(op)) {
68352
+ return fail("failure", "operation_mismatch");
68353
+ }
68354
+ if (!sameHead(receipt.bound_head_sha, input.prHeadSha, allowPrefix)) {
68355
+ return fail("failure", "stale_head");
68356
+ }
68357
+ if (rc.expected_fingerprint != null && receipt.verdict_fingerprint !== rc.expected_fingerprint) {
68358
+ return fail("failure", "fingerprint_mismatch");
68359
+ }
68360
+ if (rc.expected_body_hash != null && receipt.body_hash !== rc.expected_body_hash) {
68361
+ return fail("failure", "body_hash_mismatch");
68362
+ }
68363
+ if (rc.repository && receipt.target_id && !targetMatches(receipt.target_id, rc.repository)) {
68364
+ return fail("failure", "target_mismatch");
68365
+ }
68366
+ if (!isAllowClass(receipt, allowWarnMerge)) {
68367
+ return fail("failure", "decision_not_allow");
68368
+ }
68369
+ const inescapable_merge = enforcement_state === "ENFORCING" && protection.admin_bypass_possible === false;
68370
+ let residual;
68371
+ if (!inescapable_merge) {
68372
+ if (enforcement_state === "ENFORCING")
68373
+ residual = "admin_bypass_open";
68374
+ else if (enforcement_state === "ADVISORY")
68375
+ residual = "protection_advisory_only";
68376
+ else
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
+ }
68385
+ }
68386
+ return {
68387
+ merge_allowed: true,
68388
+ state: "success",
68389
+ reason: "allow_current_head",
68390
+ enforcement_state,
68391
+ inescapable_merge,
68392
+ ...residual ? { residual } : {},
68393
+ detail
68394
+ };
68395
+ }
68396
+ }
68397
+ });
68398
+
68399
+ // node_modules/@coderifts/agent-guard/dist/cjs/deploy-gate.js
68400
+ var require_deploy_gate = __commonJS({
68401
+ "node_modules/@coderifts/agent-guard/dist/cjs/deploy-gate.js"(exports2) {
68402
+ "use strict";
68403
+ Object.defineProperty(exports2, "__esModule", { value: true });
68404
+ exports2.deployGate = deployGate;
68405
+ function norm(s) {
68406
+ return String(s == null ? "" : s).trim().toLowerCase();
68407
+ }
68408
+ function sameNorm(a, b, allowPrefix) {
68409
+ const na = norm(a);
68410
+ const nb = norm(b);
68411
+ if (!na || !nb)
68412
+ return false;
68413
+ if (na === nb)
68414
+ return true;
68415
+ if (allowPrefix && na.length >= 7 && nb.length >= 7 && (na.startsWith(nb) || nb.startsWith(na)))
68416
+ return true;
68417
+ return false;
68418
+ }
68419
+ function isAllowClass(receipt, allowWarnDeploy) {
68420
+ const dec = receipt.decision;
68421
+ const decisionOk = dec === "ALLOW" || dec === "WARN" && allowWarnDeploy === true;
68422
+ if (!decisionOk)
68423
+ return false;
68424
+ const ea = receipt.execution_action;
68425
+ if (ea === void 0 || ea === null || ea === "")
68426
+ return true;
68427
+ return ea === "CONTINUE" || ea === "CONTINUE_WITH_MONITORING";
68428
+ }
68429
+ function idMatchesName(targetId, name) {
68430
+ const t = norm(targetId);
68431
+ const r = norm(name);
68432
+ return t === r || t === `svc:${r}` || t === `repo:${r}` || t.endsWith(`:${r}`) || t.endsWith(`/${r}`);
68433
+ }
68434
+ function deployGate(input) {
68435
+ const target = input.deployTarget || {};
68436
+ const rc = input.requiredContext || {};
68437
+ const enf = rc.enforcement || { enforcement: "UNKNOWN", bypass_possible: true };
68438
+ const enforcement_state = enf.enforcement;
68439
+ const opRequired = rc.operation ?? "deploy";
68440
+ const requireEnv = enforcement_state === "ENFORCING" || rc.require_bound_environment !== false;
68441
+ const requireArt = enforcement_state === "ENFORCING" || rc.require_bound_artifact !== false;
68442
+ const allowPending = input.allowPending ?? rc.allowPending ?? false;
68443
+ const allowWarnDeploy = input.allowWarnDeploy ?? rc.allowWarnDeploy ?? false;
68444
+ const allowPrefix = input.allowPrefixCompare ?? rc.allowPrefixCompare ?? false;
68445
+ const receipt = input.receipt;
68446
+ const detail = {
68447
+ environment: norm(target.environment),
68448
+ artifact_id: norm(target.artifact_id),
68449
+ bound_environment: receipt && receipt.bound_environment != null ? norm(receipt.bound_environment) : null,
68450
+ bound_artifact_id: receipt && receipt.bound_artifact_id != null ? norm(receipt.bound_artifact_id) : null,
68451
+ operation: receipt && receipt.operation != null ? String(receipt.operation) : null
68452
+ };
68453
+ const deny = (state, reason) => ({
68454
+ deploy_allowed: false,
68455
+ state,
68456
+ reason,
68457
+ enforcement_state,
68458
+ inescapable_deploy: false,
68459
+ detail
68460
+ });
68461
+ if (!target.environment || String(target.environment).trim() === "" || !target.artifact_id || String(target.artifact_id).trim() === "") {
68462
+ return deny(allowPending ? "pending" : "failure", "inputs_incomplete");
68463
+ }
68464
+ if (receipt === null || receipt === void 0) {
68465
+ return deny(allowPending ? "pending" : "failure", "no_receipt");
68466
+ }
68467
+ if (receipt.currently_authorized !== true) {
68468
+ return deny("failure", "receipt_not_authorized");
68469
+ }
68470
+ if (receipt.operation == null || norm(receipt.operation) !== norm(opRequired)) {
68471
+ return deny("failure", "operation_mismatch");
68472
+ }
68473
+ if (requireEnv) {
68474
+ if (!receipt.bound_environment || !sameNorm(receipt.bound_environment, target.environment, allowPrefix)) {
68475
+ return deny("failure", "env_mismatch");
68476
+ }
68477
+ } else if (receipt.bound_environment && !sameNorm(receipt.bound_environment, target.environment, allowPrefix)) {
68478
+ return deny("failure", "env_mismatch");
68479
+ }
68480
+ if (requireArt) {
68481
+ if (!receipt.bound_artifact_id || !sameNorm(receipt.bound_artifact_id, target.artifact_id, allowPrefix)) {
68482
+ return deny("failure", "stale_artifact");
68483
+ }
68484
+ } else if (receipt.bound_artifact_id && !sameNorm(receipt.bound_artifact_id, target.artifact_id, allowPrefix)) {
68485
+ return deny("failure", "stale_artifact");
68486
+ }
68487
+ if (rc.expected_fingerprint != null && receipt.verdict_fingerprint !== rc.expected_fingerprint) {
68488
+ return deny("failure", "fingerprint_mismatch");
68489
+ }
68490
+ if (rc.expected_body_hash != null && receipt.body_hash !== rc.expected_body_hash) {
68491
+ return deny("failure", "body_hash_mismatch");
68492
+ }
68493
+ if (rc.service && receipt.target_id) {
68494
+ if (!idMatchesName(receipt.target_id, rc.service))
68495
+ return deny("failure", "target_mismatch");
68496
+ } else if (rc.repository && receipt.target_id) {
68497
+ if (!idMatchesName(receipt.target_id, rc.repository))
68498
+ return deny("failure", "target_mismatch");
68499
+ }
68500
+ if (!isAllowClass(receipt, allowWarnDeploy)) {
68501
+ return deny("failure", "decision_not_allow");
68502
+ }
68503
+ const inescapable_deploy = enforcement_state === "ENFORCING" && enf.bypass_possible === false;
68504
+ let residual;
68505
+ if (!inescapable_deploy) {
68506
+ if (enforcement_state === "ENFORCING")
68507
+ residual = "bypass_open";
68508
+ else
68509
+ residual = "enforcement_not_configured";
68510
+ }
68511
+ return {
68512
+ deploy_allowed: true,
68513
+ state: "success",
68514
+ reason: "allow_current_deploy",
68515
+ enforcement_state,
68516
+ inescapable_deploy,
68517
+ ...residual ? { residual } : {},
68518
+ detail
68519
+ };
68520
+ }
68521
+ }
68522
+ });
68523
+
68524
+ // node_modules/@coderifts/agent-guard/dist/cjs/coverage-report.js
68525
+ var require_coverage_report = __commonJS({
68526
+ "node_modules/@coderifts/agent-guard/dist/cjs/coverage-report.js"(exports2) {
68527
+ "use strict";
68528
+ Object.defineProperty(exports2, "__esModule", { value: true });
68529
+ exports2.coverageReport = coverageReport;
68530
+ var TEMPLATES = {
68531
+ claim_fully_enforced: "All applicable CodeRifts placements are enforcing and non-bypassable for this target. Residuals outside tetrad (e.g. infra break-glass) may still exist.",
68532
+ claim_partially_enforced: "Partial enforcement: some applicable placements enforce; open gaps: {residuals}.",
68533
+ claim_advisory_only: "CodeRifts is present but no applicable placement is fully enforcing. Gaps: {residuals}.",
68534
+ claim_content_blocked: "Contract artifact content is not fully resolved; enforcement of preflight content is incomplete. Gaps: {residuals}.",
68535
+ claim_unknown: "One or more applicable placements cannot be observed. Cannot attest full enforcement. Gaps: {residuals}.",
68536
+ claim_not_applicable: "No CodeRifts placements are in scope for this target."
68537
+ };
68538
+ var OVERALL_TO_KEY = {
68539
+ FULLY_ENFORCED: "claim_fully_enforced",
68540
+ PARTIALLY_ENFORCED: "claim_partially_enforced",
68541
+ ADVISORY_ONLY: "claim_advisory_only",
68542
+ CONTENT_BLOCKED: "claim_content_blocked",
68543
+ UNKNOWN: "claim_unknown",
68544
+ NOT_APPLICABLE: "claim_not_applicable"
68545
+ };
68546
+ function computeRuntime(applicable, input) {
68547
+ if (!applicable)
68548
+ return { strength: "EXCLUDED", residuals: [], summary: { enforcement_or_coverage: input?.coverage ?? "N/A", inescapable_flag: input?.inescapable_runtime ?? null } };
68549
+ if (input == null)
68550
+ return { strength: "UNKNOWN", residuals: ["runtime_state_missing"], summary: { enforcement_or_coverage: "MISSING", inescapable_flag: null } };
68551
+ const residuals = [...input.residuals ?? []];
68552
+ let strength;
68553
+ if (input.coverage === "COMPLETE" && input.inescapable_runtime === true)
68554
+ strength = "ENFORCING";
68555
+ else if (input.coverage === "UNKNOWN")
68556
+ strength = "UNKNOWN";
68557
+ else
68558
+ strength = "WEAK";
68559
+ if (input.coverage === "BYPASSED")
68560
+ residuals.push("runtime_bypassed");
68561
+ return { strength, residuals, summary: { enforcement_or_coverage: input.coverage, inescapable_flag: input.inescapable_runtime } };
68562
+ }
68563
+ function computeMerge(applicable, input) {
68564
+ if (!applicable)
68565
+ return { strength: "EXCLUDED", residuals: [], summary: { enforcement_or_coverage: input?.enforcement_state ?? "N/A", inescapable_flag: input?.inescapable_merge ?? null } };
68566
+ if (input == null)
68567
+ return { strength: "UNKNOWN", residuals: ["merge_state_missing"], summary: { enforcement_or_coverage: "MISSING", inescapable_flag: null } };
68568
+ const residuals = [...input.residuals ?? []];
68569
+ let strength;
68570
+ if (input.inescapable_merge === true && input.enforcement_state === "ENFORCING")
68571
+ strength = "ENFORCING";
68572
+ else if (input.inescapable_merge === true) {
68573
+ strength = "WEAK";
68574
+ residuals.push("inescapable_flag_inconsistent");
68575
+ } else if (input.enforcement_state === "UNKNOWN")
68576
+ strength = "UNKNOWN";
68577
+ else
68578
+ strength = "WEAK";
68579
+ if (strength === "WEAK") {
68580
+ if (input.enforcement_state === "ENFORCING" && input.inescapable_merge === false)
68581
+ residuals.push("admin_bypass_open");
68582
+ else if (input.enforcement_state === "ABSENT")
68583
+ residuals.push("merge_gate_not_configured");
68584
+ else if (input.enforcement_state === "ADVISORY")
68585
+ residuals.push("merge_gate_advisory");
68586
+ }
68587
+ return { strength, residuals, summary: { enforcement_or_coverage: input.enforcement_state, inescapable_flag: input.inescapable_merge } };
68588
+ }
68589
+ function computeDeploy(applicable, input) {
68590
+ if (!applicable)
68591
+ return { strength: "EXCLUDED", residuals: [], summary: { enforcement_or_coverage: input?.enforcement_state ?? "N/A", inescapable_flag: input?.inescapable_deploy ?? null } };
68592
+ if (input == null)
68593
+ return { strength: "UNKNOWN", residuals: ["deploy_state_missing"], summary: { enforcement_or_coverage: "MISSING", inescapable_flag: null } };
68594
+ const residuals = [...input.residuals ?? []];
68595
+ let strength;
68596
+ if (input.inescapable_deploy === true && input.enforcement_state === "ENFORCING")
68597
+ strength = "ENFORCING";
68598
+ else if (input.inescapable_deploy === true) {
68599
+ strength = "WEAK";
68600
+ residuals.push("inescapable_flag_inconsistent");
68601
+ } else if (input.enforcement_state === "UNKNOWN")
68602
+ strength = "UNKNOWN";
68603
+ else
68604
+ strength = "WEAK";
68605
+ if (strength === "WEAK") {
68606
+ if (input.enforcement_state === "ENFORCING" && input.inescapable_deploy === false)
68607
+ residuals.push("bypass_open");
68608
+ else if (input.enforcement_state === "ABSENT")
68609
+ residuals.push("deploy_path_ungated");
68610
+ else if (input.enforcement_state === "ADVISORY")
68611
+ residuals.push("deploy_gate_advisory");
68612
+ }
68613
+ return { strength, residuals, summary: { enforcement_or_coverage: input.enforcement_state, inescapable_flag: input.inescapable_deploy } };
68614
+ }
68615
+ function computeContent(applicable, input) {
68616
+ if (!applicable)
68617
+ return { strength: "EXCLUDED", residuals: [], summary: { enforcement_or_coverage: input?.coverage ?? "N/A", inescapable_flag: input?.artifacts_ready ?? null } };
68618
+ if (input == null)
68619
+ return { strength: "UNKNOWN", residuals: ["content_state_missing"], summary: { enforcement_or_coverage: "MISSING", inescapable_flag: null } };
68620
+ const residuals = [...input.residuals ?? []];
68621
+ let strength;
68622
+ if (input.coverage === "COMPLETE" || input.coverage === "EMPTY")
68623
+ strength = "ENFORCING";
68624
+ else if (input.coverage === "UNRESOLVED") {
68625
+ strength = "WEAK";
68626
+ residuals.push("content_unresolved");
68627
+ } else if (input.coverage === "PARTIAL") {
68628
+ strength = "WEAK";
68629
+ residuals.push("content_partial");
68630
+ } else
68631
+ strength = "UNKNOWN";
68632
+ return { strength, residuals, summary: { enforcement_or_coverage: input.coverage, inescapable_flag: input.artifacts_ready ?? null } };
68633
+ }
68634
+ function coverageReport(input) {
68635
+ const applicability = input.applicability || { runtime: false, merge: false, deploy: false, content: false };
68636
+ const computed = {
68637
+ runtime: computeRuntime(applicability.runtime === true, input.runtime),
68638
+ merge: computeMerge(applicability.merge === true, input.merge),
68639
+ deploy: computeDeploy(applicability.deploy === true, input.deploy),
68640
+ content: computeContent(applicability.content === true, input.content)
68641
+ };
68642
+ const order = ["runtime", "merge", "deploy", "content"];
68643
+ const isApplicable = (p) => applicability[p] === true;
68644
+ const applicableStrengths = order.filter(isApplicable).map((p) => computed[p].strength);
68645
+ const contentApplicable = isApplicable("content");
68646
+ const contentUnresolved = contentApplicable && input.content != null && input.content.coverage === "UNRESOLVED";
68647
+ const weakPlacements = order.filter((p) => isApplicable(p) && computed[p].strength === "WEAK");
68648
+ let overall;
68649
+ if (applicableStrengths.length === 0) {
68650
+ overall = "NOT_APPLICABLE";
68651
+ } else if (applicableStrengths.every((s) => s === "ENFORCING")) {
68652
+ overall = "FULLY_ENFORCED";
68653
+ } else if (applicableStrengths.some((s) => s === "WEAK") && applicableStrengths.some((s) => s === "ENFORCING")) {
68654
+ overall = contentUnresolved ? "CONTENT_BLOCKED" : "PARTIALLY_ENFORCED";
68655
+ } else if (applicableStrengths.some((s) => s === "WEAK")) {
68656
+ overall = contentUnresolved && weakPlacements.every((p) => p === "content") ? "CONTENT_BLOCKED" : "ADVISORY_ONLY";
68657
+ } else {
68658
+ overall = "UNKNOWN";
68659
+ }
68660
+ const residualSet = /* @__PURE__ */ new Set();
68661
+ for (const p of order)
68662
+ if (isApplicable(p))
68663
+ for (const r of computed[p].residuals)
68664
+ residualSet.add(r);
68665
+ const residuals = [...residualSet].sort();
68666
+ const honest_claim_key = OVERALL_TO_KEY[overall];
68667
+ const honest_claim_language = TEMPLATES[honest_claim_key].replace("{residuals}", residuals.length ? residuals.join(", ") : "none");
68668
+ const flags = {
68669
+ may_claim_inescapable_runtime: isApplicable("runtime") && computed.runtime.strength === "ENFORCING",
68670
+ may_claim_inescapable_merge: isApplicable("merge") && computed.merge.strength === "ENFORCING",
68671
+ may_claim_inescapable_deploy: isApplicable("deploy") && computed.deploy.strength === "ENFORCING",
68672
+ may_claim_full_tetrad: overall === "FULLY_ENFORCED"
68673
+ };
68674
+ const per_placement = order.map((p) => ({
68675
+ placement: p,
68676
+ applicable: isApplicable(p),
68677
+ strength: computed[p].strength,
68678
+ summary: computed[p].summary,
68679
+ residuals: isApplicable(p) ? [...new Set(computed[p].residuals)].sort() : []
68680
+ }));
68681
+ return { overall_coverage: overall, per_placement, residuals, honest_claim_key, honest_claim_language, flags };
68682
+ }
68683
+ }
68684
+ });
68685
+
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
68808
+ var require_cjs4 = __commonJS({
68809
+ "node_modules/@coderifts/agent-guard/dist/cjs/index.js"(exports2) {
68810
+ "use strict";
68811
+ Object.defineProperty(exports2, "__esModule", { value: true });
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;
68813
+ var guard_js_1 = require_guard();
68814
+ Object.defineProperty(exports2, "guardToolCall", { enumerable: true, get: function() {
68815
+ return guard_js_1.guardToolCall;
68816
+ } });
68817
+ var detector_js_1 = require_detector();
68818
+ Object.defineProperty(exports2, "builtinDetector", { enumerable: true, get: function() {
68819
+ return detector_js_1.builtinDetector;
68820
+ } });
68821
+ Object.defineProperty(exports2, "DETECTOR_VERSION", { enumerable: true, get: function() {
68822
+ return detector_js_1.DETECTOR_VERSION;
68823
+ } });
68824
+ var receipt_binding_js_1 = require_receipt_binding();
68825
+ Object.defineProperty(exports2, "bindReceiptToEnvelope", { enumerable: true, get: function() {
68826
+ return receipt_binding_js_1.bindReceiptToEnvelope;
68827
+ } });
68828
+ Object.defineProperty(exports2, "computeBodyHash", { enumerable: true, get: function() {
68829
+ return receipt_binding_js_1.computeBodyHash;
68830
+ } });
68831
+ Object.defineProperty(exports2, "canonicalJson", { enumerable: true, get: function() {
68832
+ return receipt_binding_js_1.canonicalJson;
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
+ } });
68847
+ var enforcement_gate_js_1 = require_enforcement_gate();
68848
+ Object.defineProperty(exports2, "evaluateEnvelope", { enumerable: true, get: function() {
68849
+ return enforcement_gate_js_1.evaluateEnvelope;
68850
+ } });
68851
+ Object.defineProperty(exports2, "computeArtifactDigest", { enumerable: true, get: function() {
68852
+ return enforcement_gate_js_1.computeArtifactDigest;
68853
+ } });
68854
+ Object.defineProperty(exports2, "computeBundleFingerprint", { enumerable: true, get: function() {
68855
+ return enforcement_gate_js_1.computeBundleFingerprint;
68856
+ } });
68857
+ var sdk_1 = require_cjs3();
68858
+ Object.defineProperty(exports2, "readDecision", { enumerable: true, get: function() {
68859
+ return sdk_1.readDecision;
68860
+ } });
68861
+ var session_taint_js_1 = require_session_taint();
68862
+ Object.defineProperty(exports2, "SessionTaintTracker", { enumerable: true, get: function() {
68863
+ return session_taint_js_1.SessionTaintTracker;
68864
+ } });
68865
+ Object.defineProperty(exports2, "SESSION_TAINT_VERSION", { enumerable: true, get: function() {
68866
+ return session_taint_js_1.SESSION_TAINT_VERSION;
68867
+ } });
68868
+ Object.defineProperty(exports2, "updateSession", { enumerable: true, get: function() {
68869
+ return session_taint_js_1.updateSession;
68870
+ } });
68871
+ Object.defineProperty(exports2, "evaluate", { enumerable: true, get: function() {
68872
+ return session_taint_js_1.evaluate;
68873
+ } });
68874
+ Object.defineProperty(exports2, "computeTainted", { enumerable: true, get: function() {
68875
+ return session_taint_js_1.computeTainted;
68876
+ } });
68877
+ Object.defineProperty(exports2, "emptySessionState", { enumerable: true, get: function() {
68878
+ return session_taint_js_1.emptySessionState;
68879
+ } });
68880
+ Object.defineProperty(exports2, "projectState", { enumerable: true, get: function() {
68881
+ return session_taint_js_1.projectState;
68882
+ } });
68883
+ Object.defineProperty(exports2, "classifyCommand", { enumerable: true, get: function() {
68884
+ return session_taint_js_1.classifyCommand;
68885
+ } });
68886
+ Object.defineProperty(exports2, "pathClass", { enumerable: true, get: function() {
68887
+ return session_taint_js_1.pathClass;
68888
+ } });
68889
+ Object.defineProperty(exports2, "deriveKeySignal", { enumerable: true, get: function() {
68890
+ return session_taint_js_1.deriveKeySignal;
68891
+ } });
68892
+ var artifact_resolver_js_1 = require_artifact_resolver();
68893
+ Object.defineProperty(exports2, "resolveArtifacts", { enumerable: true, get: function() {
68894
+ return artifact_resolver_js_1.resolve;
68895
+ } });
68896
+ Object.defineProperty(exports2, "classifyByName", { enumerable: true, get: function() {
68897
+ return artifact_resolver_js_1.classifyByName;
68898
+ } });
68899
+ var resolver_glob_js_1 = require_resolver_glob();
68900
+ Object.defineProperty(exports2, "matchGlob", { enumerable: true, get: function() {
68901
+ return resolver_glob_js_1.matchGlob;
68902
+ } });
68903
+ Object.defineProperty(exports2, "globToRegExp", { enumerable: true, get: function() {
68904
+ return resolver_glob_js_1.globToRegExp;
68905
+ } });
68906
+ var tool_registry_js_1 = require_tool_registry();
68907
+ Object.defineProperty(exports2, "guardToolRegistry", { enumerable: true, get: function() {
68908
+ return tool_registry_js_1.guardToolRegistry;
68909
+ } });
68910
+ Object.defineProperty(exports2, "RegistryConstructionError", { enumerable: true, get: function() {
68911
+ return tool_registry_js_1.RegistryConstructionError;
68912
+ } });
68913
+ var merge_gate_js_1 = require_merge_gate();
68914
+ Object.defineProperty(exports2, "gateDecision", { enumerable: true, get: function() {
68915
+ return merge_gate_js_1.gateDecision;
68916
+ } });
68917
+ var deploy_gate_js_1 = require_deploy_gate();
68918
+ Object.defineProperty(exports2, "deployGate", { enumerable: true, get: function() {
68919
+ return deploy_gate_js_1.deployGate;
68920
+ } });
68921
+ var coverage_report_js_1 = require_coverage_report();
68922
+ Object.defineProperty(exports2, "coverageReport", { enumerable: true, get: function() {
68923
+ return coverage_report_js_1.coverageReport;
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
+ } });
68929
+ }
68930
+ });
68931
+
68932
+ // src/commands/deploy-gate.js
68933
+ var require_deploy_gate2 = __commonJS({
68934
+ "src/commands/deploy-gate.js"(exports2, module2) {
68935
+ "use strict";
68936
+ var fs = require("fs");
68937
+ var path = require("path");
68938
+ var chalk = require_source();
68939
+ var { deployGate } = require_cjs4();
68940
+ var { renderJson } = require_json2();
68941
+ if (process.env.NO_COLOR) chalk.level = 0;
68942
+ var REPAIRABLE = /* @__PURE__ */ new Set(["env_mismatch", "stale_artifact", "operation_mismatch", "receipt_not_authorized", "fingerprint_mismatch", "body_hash_mismatch"]);
68943
+ function enforceSignal(options) {
68944
+ return options && options.enforce === true || String(process.env.CODERIFTS_DEPLOY_ENFORCE || "").toLowerCase() === "true";
68945
+ }
68946
+ function observeCDEnforcement(options = {}) {
68947
+ const envVal = String(process.env.CODERIFTS_DEPLOY_ENFORCE || "").toLowerCase();
68948
+ let enforcement;
68949
+ if (enforceSignal(options)) enforcement = "ENFORCING";
68950
+ else if (envVal === "unknown") enforcement = "UNKNOWN";
68951
+ else enforcement = "ADVISORY";
68952
+ const bypass_possible = String(process.env.CODERIFTS_DEPLOY_NO_BYPASS || "").toLowerCase() !== "true";
68953
+ return {
68954
+ enforcement,
68955
+ bypass_possible,
68956
+ step_is_required: enforcement === "ENFORCING",
68957
+ required_step_name: "CodeRifts / deploy-gate",
68958
+ attestation_source: "cli_flag"
68959
+ };
68960
+ }
68961
+ function deployReportResiduals(state, inescapable, enforcement) {
68962
+ const out = [];
68963
+ if (state === "success" && inescapable !== true) {
68964
+ if (enforcement === "ENFORCING") out.push("bypass_open");
68965
+ else if (enforcement === "ADVISORY") out.push("deploy_gate_advisory");
68966
+ else if (enforcement === "ABSENT") out.push("deploy_path_ungated");
68967
+ }
68968
+ return out;
68969
+ }
68970
+ function deployCoverageInput(enforcement_state, inescapable_deploy) {
68971
+ return { enforcement_state, inescapable_deploy: inescapable_deploy === true, applicability_attested: true };
68972
+ }
68973
+ function deployBind({ environment, artifact_id, receipt, observed_cd_enforcement, expected_fingerprint, expected_body_hash }) {
68974
+ const attested_enforcement = observed_cd_enforcement && observed_cd_enforcement.enforcement || "UNKNOWN";
68975
+ if (!receipt) {
68976
+ return {
68977
+ deploy_check_status: "pending",
68978
+ reason: "no_receipt",
68979
+ must_re_preflight: true,
68980
+ attested_enforcement,
68981
+ gate: null,
68982
+ report_residuals: [],
68983
+ coverage_deploy_input: deployCoverageInput(attested_enforcement, false)
68984
+ };
68985
+ }
68986
+ const requiredContext = {
68987
+ operation: "deploy",
68988
+ enforcement: {
68989
+ enforcement: attested_enforcement,
68990
+ // fail-closed: bypass is possible unless observation proved it disabled.
68991
+ bypass_possible: !(observed_cd_enforcement && observed_cd_enforcement.bypass_possible === false)
68992
+ }
68993
+ };
68994
+ if (attested_enforcement === "ENFORCING") {
68995
+ if (expected_fingerprint != null) requiredContext.expected_fingerprint = expected_fingerprint;
68996
+ if (expected_body_hash != null) requiredContext.expected_body_hash = expected_body_hash;
68997
+ }
68998
+ const gate = deployGate({ deployTarget: { environment, artifact_id }, receipt, requiredContext });
68999
+ const inescapable_deploy = gate.inescapable_deploy === true;
69000
+ return {
69001
+ deploy_check_status: gate.state,
69002
+ reason: gate.reason,
69003
+ must_re_preflight: REPAIRABLE.has(gate.reason),
69004
+ attested_enforcement,
69005
+ gate: { deploy_allowed: gate.deploy_allowed, reason: gate.reason, inescapable_deploy },
69006
+ report_residuals: deployReportResiduals(gate.state, inescapable_deploy, attested_enforcement),
69007
+ coverage_deploy_input: deployCoverageInput(attested_enforcement, inescapable_deploy)
69008
+ };
69009
+ }
69010
+ function clampExit(deployCheckStatus, enforce) {
69011
+ if (deployCheckStatus === "success") return 0;
69012
+ if (deployCheckStatus === "failure" && enforce === true) return 1;
69013
+ return 0;
69014
+ }
69015
+ function readReceiptFile(filePath) {
69016
+ if (!filePath) return null;
69017
+ const resolved = path.resolve(filePath);
69018
+ if (!fs.existsSync(resolved)) return null;
69019
+ try {
69020
+ return JSON.parse(fs.readFileSync(resolved, "utf-8"));
69021
+ } catch (_) {
69022
+ return null;
69023
+ }
69024
+ }
69025
+ function renderDeployGateTerminal(bind, enforce) {
69026
+ const g = bind.gate;
69027
+ const color = bind.deploy_check_status === "success" ? chalk.green : bind.deploy_check_status === "failure" ? chalk.red : chalk.yellow;
69028
+ const lines = [];
69029
+ lines.push("");
69030
+ lines.push(chalk.bold(` CodeRifts deploy-gate \u2014 ${color(bind.deploy_check_status.toUpperCase())}`));
69031
+ lines.push(` Reason: ${bind.reason}`);
69032
+ lines.push(` Enforcement: ${bind.attested_enforcement}`);
69033
+ lines.push(` inescapable_deploy: ${g ? g.inescapable_deploy : false}`);
69034
+ if (bind.report_residuals.length) lines.push(` Residuals: ${bind.report_residuals.join(", ")}`);
69035
+ if (bind.must_re_preflight) lines.push(chalk.yellow(" Action: re-preflight this { environment, artifact } \u2014 the receipt does not authorize it."));
69036
+ lines.push("");
69037
+ lines.push(enforce ? chalk.dim(" Enforcing \u2014 a failing gate exits non-zero (blocks the deploy step).") : chalk.dim(" Advisory (phase 1) \u2014 does not block the deploy (exit 0)."));
69038
+ lines.push("");
69039
+ return lines.join("\n");
69040
+ }
69041
+ async function runDeployGate(options = {}) {
69042
+ const environment = options.env;
69043
+ const artifactId = options.artifact;
69044
+ if (!environment || !artifactId) {
69045
+ console.error(chalk.red("Error: --env and --artifact are required."));
69046
+ process.exit(1);
69047
+ return;
69048
+ }
69049
+ const enforce = enforceSignal(options);
69050
+ const receipt = readReceiptFile(options.receipt);
69051
+ const observed = observeCDEnforcement({ enforce });
69052
+ const bind = deployBind({ environment, artifact_id: artifactId, receipt, observed_cd_enforcement: observed });
69053
+ const code = clampExit(bind.deploy_check_status, enforce);
69054
+ if (options.json) {
69055
+ console.log(renderJson({ command: "deploy-gate", environment, artifact_id: artifactId, phase: enforce ? "enforcing" : "advisory", exit_code: code, ...bind }));
69056
+ } else {
69057
+ console.log(renderDeployGateTerminal(bind, enforce));
69058
+ }
69059
+ process.exit(code);
69060
+ }
69061
+ module2.exports = {
69062
+ runDeployGate,
69063
+ deployBind,
69064
+ observeCDEnforcement,
69065
+ clampExit,
69066
+ readReceiptFile,
69067
+ renderDeployGateTerminal
69068
+ };
69069
+ }
69070
+ });
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
+
65408
69516
  // src/commands/init.js
65409
69517
  var require_init = __commonJS({
65410
69518
  "src/commands/init.js"(exports2, module2) {
@@ -76068,7 +80176,7 @@ var require_zipWith = __commonJS({
76068
80176
  });
76069
80177
 
76070
80178
  // node_modules/rxjs/dist/cjs/index.js
76071
- var require_cjs3 = __commonJS({
80179
+ var require_cjs5 = __commonJS({
76072
80180
  "node_modules/rxjs/dist/cjs/index.js"(exports2) {
76073
80181
  "use strict";
76074
80182
  var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
@@ -77385,7 +81493,7 @@ var require_run_async = __commonJS({
77385
81493
  var require_utils3 = __commonJS({
77386
81494
  "node_modules/inquirer/lib/utils/utils.js"(exports2) {
77387
81495
  "use strict";
77388
- var { from, of } = require_cjs3();
81496
+ var { from, of } = require_cjs5();
77389
81497
  var runAsync = require_run_async();
77390
81498
  exports2.fetchAsyncQuestionProperty = function(question, prop, answers) {
77391
81499
  if (typeof question[prop] !== "function") {
@@ -77410,7 +81518,7 @@ var require_prompt = __commonJS({
77410
81518
  get: require_get2(),
77411
81519
  set: require_set3()
77412
81520
  };
77413
- var { defer, empty, from, of } = require_cjs3();
81521
+ var { defer, empty, from, of } = require_cjs5();
77414
81522
  var { concatMap, filter, publish, reduce } = require_operators();
77415
81523
  var runAsync = require_run_async();
77416
81524
  var utils = require_utils3();
@@ -80124,7 +84232,7 @@ var require_base = __commonJS({
80124
84232
  var require_events = __commonJS({
80125
84233
  "node_modules/inquirer/lib/utils/events.js"(exports2, module2) {
80126
84234
  "use strict";
80127
- var { fromEvent } = require_cjs3();
84235
+ var { fromEvent } = require_cjs5();
80128
84236
  var { filter, map, share, takeUntil } = require_operators();
80129
84237
  function normalizeKeypressEvents(value, key) {
80130
84238
  return { value, key: key || {} };
@@ -90922,7 +95030,7 @@ var require_editor = __commonJS({
90922
95030
  var { editAsync } = require_commonjs();
90923
95031
  var Base = require_base();
90924
95032
  var observe = require_events();
90925
- var { Subject } = require_cjs3();
95033
+ var { Subject } = require_cjs5();
90926
95034
  var EditorPrompt = class extends Base {
90927
95035
  /**
90928
95036
  * Start the Inquiry session
@@ -91093,6 +95201,8 @@ ${HOOK_MARKER}
91093
95201
  # Checks API spec changes before pushing.
91094
95202
  # The pre-push hook receives lines on stdin:
91095
95203
  # <local ref> <local sha> <remote ref> <remote sha>
95204
+ #
95205
+ # Re-install after CLI upgrades: coderifts hook install
91096
95206
 
91097
95207
  CODERIFTS_API_KEY=$(git config coderifts.apiKey)
91098
95208
  SPEC_PATH=$(git config coderifts.specPath || echo "api/openapi.yaml")
@@ -91103,6 +95213,53 @@ if [ -z "$CODERIFTS_API_KEY" ]; then
91103
95213
  exit 0 # Don't block if not configured
91104
95214
  fi
91105
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
+
91106
95263
  # Read stdin lines provided by git pre-push
91107
95264
  while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do
91108
95265
  # Skip delete pushes
@@ -91110,41 +95267,93 @@ while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do
91110
95267
  continue
91111
95268
  fi
91112
95269
 
91113
- # Get the spec at the local (about-to-be-pushed) commit
91114
- HEAD_SPEC=$(git show "$LOCAL_SHA:$SPEC_PATH" 2>/dev/null)
91115
- 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
91116
95276
  continue # Spec doesn't exist in local commit, skip
91117
95277
  fi
95278
+ HEAD_SPEC=$BLOB_CONTENT
91118
95279
 
91119
- # Get the spec at the remote (already-pushed) commit
95280
+ # before = remote tip, or for new branch (zero remote SHA) a merge-base baseline
91120
95281
  if [ "$REMOTE_SHA" = "$ZERO" ]; then
91121
- # New branch \u2014 no remote baseline, use empty spec
91122
- 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
+ }
91123
95286
  else
91124
- BASE_SPEC=$(git show "$REMOTE_SHA:$SPEC_PATH" 2>/dev/null || echo "")
95287
+ BASE_REF=$REMOTE_SHA
91125
95288
  fi
91126
95289
 
91127
- # If base is empty (new spec or new branch), allow
91128
- if [ -z "$BASE_SPEC" ]; then
91129
- 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."
91130
95297
  continue
91131
95298
  fi
95299
+ BASE_SPEC=$BLOB_CONTENT
91132
95300
 
91133
95301
  # If specs are identical, nothing to check
91134
95302
  if [ "$BASE_SPEC" = "$HEAD_SPEC" ]; then
91135
95303
  continue
91136
95304
  fi
91137
95305
 
91138
- echo "CodeRifts: Checking API spec changes..."
95306
+ echo "CodeRifts: Checking API spec changes (baseline $BASE_REF)..."
91139
95307
 
91140
95308
  RESULT=$(curl -s -X POST https://app.coderifts.com/api/v1/diff \\
91141
95309
  -H "Authorization: Bearer $CODERIFTS_API_KEY" \\
91142
95310
  -H "Content-Type: application/json" \\
91143
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()))')}")
91144
95312
 
91145
- DECISION=$(echo $RESULT | python3 -c "import sys,json; print(json.load(sys.stdin).get('omega_decision','ALLOW'))" 2>/dev/null)
91146
- OMEGA=$(echo $RESULT | python3 -c "import sys,json; print(json.load(sys.stdin).get('omega_api',0))" 2>/dev/null)
91147
- 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
91148
95357
 
91149
95358
  if [ "$DECISION" = "BLOCK" ]; then
91150
95359
  echo ""
@@ -91212,6 +95421,10 @@ exit 0
91212
95421
  console.log("");
91213
95422
  console.log("Optionally set spec path (default: api/openapi.yaml):");
91214
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");
91215
95428
  }
91216
95429
  function uninstall() {
91217
95430
  const gitDir = findGitDir();
@@ -92581,6 +96794,7 @@ var require_mcp_poisoning_detector = __commonJS({
92581
96794
  "../../src/mcp-poisoning-detector.js"(exports2, module2) {
92582
96795
  "use strict";
92583
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)";
92584
96798
  var SUSPICIOUS_PATTERNS = [
92585
96799
  // Injection / "ignore your instructions" family. The trailing object
92586
96800
  // (instructions|rules|prompts|context) is OPTIONAL so "ignore previous and ..."
@@ -92593,6 +96807,21 @@ var require_mcp_poisoning_detector = __commonJS({
92593
96807
  /exfiltrate|steal|leak|send\s+to\s+external/i,
92594
96808
  // Exfiltration-intent family: an action verb targeting a sensitive payload.
92595
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,
92596
96825
  /execute\s+(shell|command|code|system)/i,
92597
96826
  /bypass\s+(auth|security|validation|filter)/i,
92598
96827
  /override\s+(safety|policy|rules?)/i,
@@ -92604,8 +96833,8 @@ var require_mcp_poisoning_detector = __commonJS({
92604
96833
  /return\s+secret|exfiltrat|leak\s+data/i
92605
96834
  ];
92606
96835
  var URL_PATTERN = /https?:\/\/[^\s)'"]+/i;
92607
- var SENSITIVE_PATH_PATTERN = /(~\/\.ssh|~\/\.cursor|~\/\.aws|\.aws\/|\.env\b|\/etc\/|mcp\.json|credentials|id_rsa|\.ssh\/|private[\s_-]?keys?)/i;
92608
- 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;
92609
96838
  var BASE64_BLOB_PATTERN = /[A-Za-z0-9+/]{40,}={0,2}/;
92610
96839
  function isLikelyBase64(s) {
92611
96840
  if (/=$/.test(s)) return true;
@@ -93140,6 +97369,17 @@ program.command("diff <old-spec> <new-spec>").description("Compare two OpenAPI s
93140
97369
  const { diff } = require_diff();
93141
97370
  await diff(oldSpec, newSpec, options);
93142
97371
  });
97372
+ program.command("deploy-gate").description("Gate a deploy on the current { environment, artifact } using a preflight receipt (phase-1 advisory)").option("--env <environment>", "Target environment (e.g. production, staging)").option("--artifact <artifact_id>", "Immutable artifact identity being deployed (content digest or commit SHA)").option("--receipt <file>", "Path to the deploy-scoped receipt JSON produced by preflight").option("--json", "Output the binding result as JSON").option("--enforce", "Treat the step as enforcing: attest ENFORCING and exit non-zero on a gate failure").action(async (options) => {
97373
+ const { runDeployGate } = require_deploy_gate2();
97374
+ await runDeployGate(options);
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
+ });
93143
97383
  program.command("init [template]").description("Generate a .coderifts.yml from a policy template (startup, growth, fintech, public-api, microservices)").action(async (template) => {
93144
97384
  const { init } = require_init();
93145
97385
  await init(template);
@@ -93166,7 +97406,11 @@ corpusCmd.command("verify", { isDefault: true }).description("Evaluate every tru
93166
97406
  const { corpusVerify } = require_corpus();
93167
97407
  corpusVerify(options);
93168
97408
  });
93169
- 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
+ });
93170
97414
  /*! Bundled license information:
93171
97415
 
93172
97416
  safe-buffer/index.js: