coderifts 7.0.0 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +35 -5
- package/dist/cli.js +1740 -300
- package/package.json +3 -3
- package/scripts/assert-guard-major.js +11 -4
package/dist/cli.js
CHANGED
|
@@ -3028,7 +3028,7 @@ var require_package = __commonJS({
|
|
|
3028
3028
|
"package.json"(exports2, module2) {
|
|
3029
3029
|
module2.exports = {
|
|
3030
3030
|
name: "coderifts",
|
|
3031
|
-
version: "
|
|
3031
|
+
version: "8.0.1",
|
|
3032
3032
|
description: "Detect breaking API changes from the command line. Works locally or with the CodeRifts cloud API.",
|
|
3033
3033
|
author: "CodeRifts <hello@coderifts.com>",
|
|
3034
3034
|
license: "MIT",
|
|
@@ -3068,13 +3068,13 @@ var require_package = __commonJS({
|
|
|
3068
3068
|
},
|
|
3069
3069
|
scripts: {
|
|
3070
3070
|
build: "node scripts/copy-corpus.js && node scripts/build.js",
|
|
3071
|
-
prepublishOnly: "node scripts/assert-guard-major.js && node scripts/assert-changelog-version.js && bash ../../scripts/freeze-gate.sh && npm run build",
|
|
3071
|
+
prepublishOnly: "node scripts/assert-guard-major.js && node scripts/assert-changelog-version.js && bash ../../scripts/freeze-gate.sh && npm run build && bash ../../scripts/release-check.sh .",
|
|
3072
3072
|
"assert-guard-major": "node scripts/assert-guard-major.js",
|
|
3073
3073
|
postinstall: "node scripts/postinstall.js",
|
|
3074
3074
|
test: "node --test test/*.test.js"
|
|
3075
3075
|
},
|
|
3076
3076
|
dependencies: {
|
|
3077
|
-
"@coderifts/agent-guard": "^
|
|
3077
|
+
"@coderifts/agent-guard": "^15.1.0",
|
|
3078
3078
|
chalk: "^4.1.2",
|
|
3079
3079
|
"cli-table3": "^0.6.4",
|
|
3080
3080
|
commander: "^12.0.0",
|
|
@@ -68128,7 +68128,7 @@ var require_client = __commonJS({
|
|
|
68128
68128
|
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
68129
68129
|
}
|
|
68130
68130
|
// ─── Internal HTTP helper ──────────────────────────────────────────────
|
|
68131
|
-
async request(method, path, body) {
|
|
68131
|
+
async request(method, path, body, extraHeaders) {
|
|
68132
68132
|
const url = `${this.baseUrl}${path}`;
|
|
68133
68133
|
const controller = new AbortController();
|
|
68134
68134
|
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
@@ -68137,7 +68137,8 @@ var require_client = __commonJS({
|
|
|
68137
68137
|
method,
|
|
68138
68138
|
headers: {
|
|
68139
68139
|
"Content-Type": "application/json",
|
|
68140
|
-
Authorization: `Bearer ${this.apiKey}
|
|
68140
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
68141
|
+
...extraHeaders || {}
|
|
68141
68142
|
},
|
|
68142
68143
|
body: body ? JSON.stringify(body) : void 0,
|
|
68143
68144
|
signal: controller.signal
|
|
@@ -68340,8 +68341,12 @@ var require_client = __commonJS({
|
|
|
68340
68341
|
* `decision` / `safe_for_agent` (authorize) or `analysis_outcome` (analyze). Call
|
|
68341
68342
|
* `analyzeChangeSet` / `authorizeChangeSet` instead to get an already-narrowed type.
|
|
68342
68343
|
*/
|
|
68343
|
-
async preflightChangeSet(req) {
|
|
68344
|
-
|
|
68344
|
+
async preflightChangeSet(req, opts) {
|
|
68345
|
+
const extra = {};
|
|
68346
|
+
const token = opts && typeof opts.scmToken === "string" ? opts.scmToken.trim() : "";
|
|
68347
|
+
if (token)
|
|
68348
|
+
extra["X-Coderifts-Scm-Token"] = token;
|
|
68349
|
+
return this.request("POST", "/api/v1/preflight", req, extra);
|
|
68345
68350
|
}
|
|
68346
68351
|
/**
|
|
68347
68352
|
* Risk-only preflight (`preflight_mode: 'analyze'`). Informational — not permission;
|
|
@@ -68350,11 +68355,11 @@ var require_client = __commonJS({
|
|
|
68350
68355
|
* The mode is fixed by this method, so the analyze branch is returned directly — there is no
|
|
68351
68356
|
* `decision` / `execution_action` / `safe_for_agent` on it, by protocol.
|
|
68352
68357
|
*/
|
|
68353
|
-
async analyzeChangeSet(req) {
|
|
68358
|
+
async analyzeChangeSet(req, opts) {
|
|
68354
68359
|
return this.preflightChangeSet({
|
|
68355
68360
|
...req,
|
|
68356
68361
|
preflight_mode: "analyze"
|
|
68357
|
-
});
|
|
68362
|
+
}, opts);
|
|
68358
68363
|
}
|
|
68359
68364
|
/**
|
|
68360
68365
|
* Operation-bound authorize preflight (`preflight_mode: 'authorize'`).
|
|
@@ -68364,11 +68369,11 @@ var require_client = __commonJS({
|
|
|
68364
68369
|
* The mode is fixed by this method, so the authorize branch is returned directly:
|
|
68365
68370
|
* `decision`, `execution_action` and `safe_for_agent` are present without narrowing.
|
|
68366
68371
|
*/
|
|
68367
|
-
async authorizeChangeSet(req) {
|
|
68372
|
+
async authorizeChangeSet(req, opts) {
|
|
68368
68373
|
return this.preflightChangeSet({
|
|
68369
68374
|
...req,
|
|
68370
68375
|
preflight_mode: "authorize"
|
|
68371
|
-
});
|
|
68376
|
+
}, opts);
|
|
68372
68377
|
}
|
|
68373
68378
|
// ─── 9. verifyReceipt ──────────────────────────────────────────────────
|
|
68374
68379
|
/**
|
|
@@ -68581,7 +68586,7 @@ var require_execution_grant = __commonJS({
|
|
|
68581
68586
|
"node_modules/@coderifts/sdk/dist/cjs/execution-grant.js"(exports2) {
|
|
68582
68587
|
"use strict";
|
|
68583
68588
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
68584
|
-
exports2.CLOCK_SKEW_LEEWAY_MS = exports2.GRANT_SIGNING_PREFIX = exports2.GRANT_VERSION = void 0;
|
|
68589
|
+
exports2.CLOCK_SKEW_LEEWAY_MS = exports2.GRANT_SIGNING_PREFIX = exports2.GRANT_VERSION_V2 = exports2.GRANT_VERSION = void 0;
|
|
68585
68590
|
exports2.afterPayloadCanonical = afterPayloadCanonical;
|
|
68586
68591
|
exports2.computeScopeHash = computeScopeHash;
|
|
68587
68592
|
exports2.receiptDigest = receiptDigest;
|
|
@@ -68592,6 +68597,7 @@ var require_execution_grant = __commonJS({
|
|
|
68592
68597
|
return leeway_js_1.CLOCK_SKEW_LEEWAY_MS;
|
|
68593
68598
|
} });
|
|
68594
68599
|
exports2.GRANT_VERSION = "cr.exec.v1";
|
|
68600
|
+
exports2.GRANT_VERSION_V2 = "cr.exec.v2";
|
|
68595
68601
|
exports2.GRANT_SIGNING_PREFIX = "crexec.v1";
|
|
68596
68602
|
var NUL = "";
|
|
68597
68603
|
var SIGNED_FIELDS = [
|
|
@@ -69226,7 +69232,7 @@ var require_cjs3 = __commonJS({
|
|
|
69226
69232
|
"node_modules/@coderifts/sdk/dist/cjs/index.js"(exports2) {
|
|
69227
69233
|
"use strict";
|
|
69228
69234
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
69229
|
-
exports2.MONITOR_ATTEST_ENVELOPE_TAG = exports2.MONITOR_ATTEST_SIGNING_PREFIX = exports2.MONITOR_ATTEST_VERSION = exports2.monitorAttestSigningInput = exports2.verifyMonitoringAttestation = exports2.ATTEST_ENVELOPE_TAG = exports2.ATTEST_SIGNING_PREFIX = exports2.ATTEST_VERSION = exports2.attestSigningInput = exports2.verifyExecutionAttestation = exports2.GRANT_SIGNING_PREFIX = exports2.GRANT_VERSION = exports2.receiptDigest = exports2.afterPayloadCanonical = exports2.computeScopeHash = exports2.verifyExecutionGrant = exports2.isIssuedInFuture = exports2.isReceiptExpired = exports2.declaresDestructiveProduction = exports2.expiryLeewayMs = exports2.CLOCK_SKEW_LEEWAY_MS = exports2.readDecision = exports2.AuthError = exports2.RateLimitError = exports2.TimeoutError = exports2.ApiError = exports2.CodeRiftsError = exports2.resetPolicyWarnForTests = exports2.warnPolicyAbsentOnce = exports2.observePolicyPresence = exports2.detectPolicyPresence = exports2.policyPresenceOf = exports2.withPolicy = exports2.POLICY_ABSENT_WARN = exports2.POLICY_MARKER = exports2.CODERIFTS_POLICY = exports2.CodeRifts = void 0;
|
|
69235
|
+
exports2.MONITOR_ATTEST_ENVELOPE_TAG = exports2.MONITOR_ATTEST_SIGNING_PREFIX = exports2.MONITOR_ATTEST_VERSION = exports2.monitorAttestSigningInput = exports2.verifyMonitoringAttestation = exports2.ATTEST_ENVELOPE_TAG = exports2.ATTEST_SIGNING_PREFIX = exports2.ATTEST_VERSION = exports2.attestSigningInput = exports2.verifyExecutionAttestation = exports2.GRANT_SIGNING_PREFIX = exports2.GRANT_VERSION_V2 = exports2.GRANT_VERSION = exports2.receiptDigest = exports2.afterPayloadCanonical = exports2.computeScopeHash = exports2.verifyExecutionGrant = exports2.isIssuedInFuture = exports2.isReceiptExpired = exports2.declaresDestructiveProduction = exports2.expiryLeewayMs = exports2.CLOCK_SKEW_LEEWAY_MS = exports2.readDecision = exports2.AuthError = exports2.RateLimitError = exports2.TimeoutError = exports2.ApiError = exports2.CodeRiftsError = exports2.resetPolicyWarnForTests = exports2.warnPolicyAbsentOnce = exports2.observePolicyPresence = exports2.detectPolicyPresence = exports2.policyPresenceOf = exports2.withPolicy = exports2.POLICY_ABSENT_WARN = exports2.POLICY_MARKER = exports2.CODERIFTS_POLICY = exports2.CodeRifts = void 0;
|
|
69230
69236
|
var client_js_1 = require_client();
|
|
69231
69237
|
Object.defineProperty(exports2, "CodeRifts", { enumerable: true, get: function() {
|
|
69232
69238
|
return client_js_1.CodeRifts;
|
|
@@ -69311,6 +69317,9 @@ var require_cjs3 = __commonJS({
|
|
|
69311
69317
|
Object.defineProperty(exports2, "GRANT_VERSION", { enumerable: true, get: function() {
|
|
69312
69318
|
return execution_grant_js_1.GRANT_VERSION;
|
|
69313
69319
|
} });
|
|
69320
|
+
Object.defineProperty(exports2, "GRANT_VERSION_V2", { enumerable: true, get: function() {
|
|
69321
|
+
return execution_grant_js_1.GRANT_VERSION_V2;
|
|
69322
|
+
} });
|
|
69314
69323
|
Object.defineProperty(exports2, "GRANT_SIGNING_PREFIX", { enumerable: true, get: function() {
|
|
69315
69324
|
return execution_grant_js_1.GRANT_SIGNING_PREFIX;
|
|
69316
69325
|
} });
|
|
@@ -70000,7 +70009,7 @@ var require_policy2 = __commonJS({
|
|
|
70000
70009
|
exports2.observePolicyPresence = observePolicyPresence;
|
|
70001
70010
|
exports2.resetPolicyWarnForTests = resetPolicyWarnForTests;
|
|
70002
70011
|
exports2.POLICY_MARKER = "A receipt authorizes ONE operation: a merge receipt does not authorize a deploy.";
|
|
70003
|
-
exports2.CODERIFTS_POLICY = 'Call `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call
|
|
70012
|
+
exports2.CODERIFTS_POLICY = 'Call `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call `preflight_change_set` for: a documentation-only change (README, guides, comments) with no contract artifact content change; a static readiness score (a different capability, not a change-set decision); or to verify a receipt you already hold (that is `verify_receipt` \u2014 see the companion-tools rule).\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nThe CodeRifts MCP server exposes exactly three tools \u2014 `preflight_change_set`, `verify_receipt`, `get_decision_details`. Do not invent or assume others.\n\nA receipt authorizes ONE operation: a merge receipt does not authorize a deploy. Before a different operation (deploy, publish), call `preflight_change_set` with `context.operation` set to that operation \u2014 reusing a differently-scoped receipt is not permitted and will fail at the gate.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational \u2014 risk only, `may_execute` is always false \u2014 and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n\nIf the host requests an execution grant (opt-in `include_execution_grant`), the grant is bound to operation + target + after-payload (`scope_hash`) and is short-lived \u2014 never reuse it after the after-payload changes.\n\nAn ATOMIC-profile grant carries `state_nonce` and is single-use at the executor \u2014 if the executor has consumed the nonce, re-preflight; do not retry the same grant.\n\nWith a proven tenant\u2194repo binding you may request `derivation:"server"` instead of assembling `artifacts[]` yourself (`context.repository` + `context.base` + `context.head` required; caller-supplied artifacts are rejected on that path).\n\nA commit is only proven when an executor attestation verifies (customer-held executor key, `cas_evidence: executor_attested`); otherwise say "authorized, commit not proven".';
|
|
70004
70013
|
exports2.POLICY_ABSENT_WARN = "CodeRifts policy text not detected in the system prompt. The agent will still see the tools, but measured evidence shows operation-scope misuse is markedly more likely without it. See https://github.com/coderifts/agent-guard#policy-delivery.";
|
|
70005
70014
|
function textHasMarker(text) {
|
|
70006
70015
|
return text.includes(exports2.POLICY_MARKER);
|
|
@@ -70079,16 +70088,196 @@ var require_policy2 = __commonJS({
|
|
|
70079
70088
|
}
|
|
70080
70089
|
});
|
|
70081
70090
|
|
|
70091
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/deny-remedy.js
|
|
70092
|
+
var require_deny_remedy = __commonJS({
|
|
70093
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/deny-remedy.js"(exports2) {
|
|
70094
|
+
"use strict";
|
|
70095
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
70096
|
+
exports2.ARGS_SHAPE = exports2.DOES_NOT_PROMISE = exports2.DENY_ERROR = void 0;
|
|
70097
|
+
exports2.buildDenyRemedy = buildDenyRemedy;
|
|
70098
|
+
exports2.denyErrorForReason = denyErrorForReason;
|
|
70099
|
+
exports2.DENY_ERROR = Object.freeze({
|
|
70100
|
+
GRANT_REQUIRED: "CODERIFTS_GRANT_REQUIRED",
|
|
70101
|
+
GRANT_INVALID: "CODERIFTS_GRANT_INVALID",
|
|
70102
|
+
GRANT_MISMATCH: "CODERIFTS_GRANT_MISMATCH"
|
|
70103
|
+
});
|
|
70104
|
+
exports2.DOES_NOT_PROMISE = "a grant does not guarantee execution (CAS may still fail)";
|
|
70105
|
+
exports2.ARGS_SHAPE = Object.freeze({
|
|
70106
|
+
artifacts: "Array<{ id, type, before, after }> \u2014 the change set being authorized",
|
|
70107
|
+
context: "{ operation, environment?, repository?, branch?, pull_request? } \u2014 operation is required for authorize"
|
|
70108
|
+
});
|
|
70109
|
+
var FINGERPRINT_RE = /^sha256:[0-9a-f]{64}$/;
|
|
70110
|
+
function buildDenyRemedy({ error, target = null, fingerprint = null, observed = null }) {
|
|
70111
|
+
if (!error || !Object.values(exports2.DENY_ERROR).includes(error))
|
|
70112
|
+
return null;
|
|
70113
|
+
const remedy = {
|
|
70114
|
+
error,
|
|
70115
|
+
// Null, never a wildcard: a surface that cannot name what it refused must
|
|
70116
|
+
// not emit a value a reader could take for "everything".
|
|
70117
|
+
target: typeof target === "string" && target.length > 0 ? target : null,
|
|
70118
|
+
// Only a well-formed fingerprint. A malformed one is dropped rather than
|
|
70119
|
+
// passed through, because a caller comparing it would get a false mismatch.
|
|
70120
|
+
fingerprint: typeof fingerprint === "string" && FINGERPRINT_RE.test(fingerprint) ? fingerprint : null,
|
|
70121
|
+
action_required: {
|
|
70122
|
+
tool: "preflight_change_set",
|
|
70123
|
+
mode: "authorize",
|
|
70124
|
+
args_shape: { ...exports2.ARGS_SHAPE }
|
|
70125
|
+
},
|
|
70126
|
+
does_not_promise: exports2.DOES_NOT_PROMISE
|
|
70127
|
+
};
|
|
70128
|
+
if (observed && typeof observed === "object")
|
|
70129
|
+
remedy.observed = observed;
|
|
70130
|
+
return remedy;
|
|
70131
|
+
}
|
|
70132
|
+
function denyErrorForReason(reason) {
|
|
70133
|
+
switch (String(reason || "").toLowerCase()) {
|
|
70134
|
+
// Nothing was presented.
|
|
70135
|
+
case "receipt_missing":
|
|
70136
|
+
case "missing_receipt":
|
|
70137
|
+
case "missing_grant_header":
|
|
70138
|
+
case "decision_missing":
|
|
70139
|
+
case "missing_decision_result":
|
|
70140
|
+
case "no_preflight_response":
|
|
70141
|
+
case "grant_not_supplied":
|
|
70142
|
+
return exports2.DENY_ERROR.GRANT_REQUIRED;
|
|
70143
|
+
// Something was presented and did not hold up.
|
|
70144
|
+
case "receipt_invalid":
|
|
70145
|
+
case "receipt_unverified":
|
|
70146
|
+
case "invalid_signature":
|
|
70147
|
+
case "unknown_key":
|
|
70148
|
+
case "unknown_kid":
|
|
70149
|
+
case "dsse_malformed":
|
|
70150
|
+
case "dsse_unsupported":
|
|
70151
|
+
case "dsse_predicate_mismatch":
|
|
70152
|
+
case "malformed":
|
|
70153
|
+
case "grant_malformed":
|
|
70154
|
+
case "grant_unverified":
|
|
70155
|
+
case "grant_expired":
|
|
70156
|
+
return exports2.DENY_ERROR.GRANT_INVALID;
|
|
70157
|
+
// It held up, but it is not about this request.
|
|
70158
|
+
case "scope_mismatch":
|
|
70159
|
+
case "target_mismatch":
|
|
70160
|
+
case "operation_mismatch":
|
|
70161
|
+
case "grant_scope_mismatch":
|
|
70162
|
+
case "mode_mismatch":
|
|
70163
|
+
case "repo_mismatch":
|
|
70164
|
+
case "base_mismatch":
|
|
70165
|
+
case "head_mismatch":
|
|
70166
|
+
case "grant_does_not_cover_path":
|
|
70167
|
+
case "grant_bound_elsewhere":
|
|
70168
|
+
case "receipt_envelope_mismatch":
|
|
70169
|
+
case "artifact_mismatch":
|
|
70170
|
+
case "grant_unbound":
|
|
70171
|
+
case "grant_wrong_audience":
|
|
70172
|
+
return exports2.DENY_ERROR.GRANT_MISMATCH;
|
|
70173
|
+
default:
|
|
70174
|
+
return null;
|
|
70175
|
+
}
|
|
70176
|
+
}
|
|
70177
|
+
}
|
|
70178
|
+
});
|
|
70179
|
+
|
|
70180
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/next-agent-step.js
|
|
70181
|
+
var require_next_agent_step = __commonJS({
|
|
70182
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/next-agent-step.js"(exports2) {
|
|
70183
|
+
"use strict";
|
|
70184
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
70185
|
+
exports2.NEXT_STEP_NOTE = exports2.NEXT_AGENT_ACTIONS = void 0;
|
|
70186
|
+
exports2.readNextAgentStep = readNextAgentStep;
|
|
70187
|
+
exports2.NEXT_AGENT_ACTIONS = [
|
|
70188
|
+
"re_preflight",
|
|
70189
|
+
"revert",
|
|
70190
|
+
"migrate",
|
|
70191
|
+
"escalate",
|
|
70192
|
+
"await_approval"
|
|
70193
|
+
];
|
|
70194
|
+
function readNextAgentStep(envelope) {
|
|
70195
|
+
if (!envelope || typeof envelope !== "object")
|
|
70196
|
+
return null;
|
|
70197
|
+
const raw = envelope.next_agent_step;
|
|
70198
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
70199
|
+
return null;
|
|
70200
|
+
const step = raw;
|
|
70201
|
+
if (typeof step.action !== "string" || step.action.length === 0)
|
|
70202
|
+
return null;
|
|
70203
|
+
return step;
|
|
70204
|
+
}
|
|
70205
|
+
exports2.NEXT_STEP_NOTE = "This is the decision's remediation suggestion, not permission; branch on execution_action.";
|
|
70206
|
+
}
|
|
70207
|
+
});
|
|
70208
|
+
|
|
70082
70209
|
// node_modules/@coderifts/agent-guard/dist/cjs/execution-grant.js
|
|
70083
70210
|
var require_execution_grant2 = __commonJS({
|
|
70084
70211
|
"node_modules/@coderifts/agent-guard/dist/cjs/execution-grant.js"(exports2) {
|
|
70085
70212
|
"use strict";
|
|
70086
70213
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
70214
|
+
exports2.V2_WIRE_FIELDS = exports2.V2_FIELD_KEYS = void 0;
|
|
70215
|
+
exports2.resolveV2Fields = resolveV2Fields;
|
|
70216
|
+
exports2.v2WireFields = v2WireFields;
|
|
70087
70217
|
exports2.isExecutionGrantEnabled = isExecutionGrantEnabled;
|
|
70088
70218
|
exports2.readExecutionGrantToken = readExecutionGrantToken;
|
|
70089
70219
|
exports2.firstArtifactId = firstArtifactId;
|
|
70090
70220
|
exports2.isSignerUnavailableError = isSignerUnavailableError;
|
|
70091
70221
|
exports2.resolveStateNonceForCall = resolveStateNonceForCall;
|
|
70222
|
+
exports2.V2_FIELD_KEYS = Object.freeze([
|
|
70223
|
+
"executorId",
|
|
70224
|
+
"adapterId",
|
|
70225
|
+
"targetUri",
|
|
70226
|
+
"tenantId",
|
|
70227
|
+
"policyHash",
|
|
70228
|
+
"audienceHash"
|
|
70229
|
+
]);
|
|
70230
|
+
function resolveV2Fields(input) {
|
|
70231
|
+
const top = input || {};
|
|
70232
|
+
const nested = input && input.executionGrant || {};
|
|
70233
|
+
const out = {};
|
|
70234
|
+
const conflicts = [];
|
|
70235
|
+
for (const key of exports2.V2_FIELD_KEYS) {
|
|
70236
|
+
const t = typeof top[key] === "string" && top[key].length > 0 ? top[key] : void 0;
|
|
70237
|
+
const n = typeof nested[key] === "string" && nested[key].length > 0 ? nested[key] : void 0;
|
|
70238
|
+
if (t !== void 0 && n !== void 0 && t !== n) {
|
|
70239
|
+
conflicts.push(` ${key}: top-level ${JSON.stringify(t)} vs executionGrant.${key} ${JSON.stringify(n)}`);
|
|
70240
|
+
continue;
|
|
70241
|
+
}
|
|
70242
|
+
const v = t !== void 0 ? t : n;
|
|
70243
|
+
if (v !== void 0)
|
|
70244
|
+
out[key] = v;
|
|
70245
|
+
}
|
|
70246
|
+
if (conflicts.length > 0) {
|
|
70247
|
+
const err = new Error(`withCodeRifts: the V2 identity fields are configured in two places and they disagree.
|
|
70248
|
+
${conflicts.join("\n")}
|
|
70249
|
+
|
|
70250
|
+
These feed DIFFERENT halves of the system \u2014 the top level binds the ATOMIC construction check and the posture receipt, the executionGrant copy goes on the authorize request \u2014 so a disagreement builds a grant against one identity and verifies against another. Set each field ONCE, at the top level; the executionGrant spelling is a deprecated alias.`);
|
|
70251
|
+
err.code = "V2_FIELDS_CONFLICT";
|
|
70252
|
+
throw err;
|
|
70253
|
+
}
|
|
70254
|
+
return out;
|
|
70255
|
+
}
|
|
70256
|
+
exports2.V2_WIRE_FIELDS = Object.freeze([
|
|
70257
|
+
["executor_id", "executorId"],
|
|
70258
|
+
["adapter_id", "adapterId"],
|
|
70259
|
+
["target_uri", "targetUri"],
|
|
70260
|
+
["tenant_id", "tenantId"],
|
|
70261
|
+
["policy_hash", "policyHash"],
|
|
70262
|
+
["audience_hash", "audienceHash"]
|
|
70263
|
+
]);
|
|
70264
|
+
function v2WireFields(config) {
|
|
70265
|
+
const g = config && config.executionGrant;
|
|
70266
|
+
const fields = {};
|
|
70267
|
+
const absent = [];
|
|
70268
|
+
if (!g || g.grantVersion !== "v2") {
|
|
70269
|
+
return { fields, absent: exports2.V2_WIRE_FIELDS.map(([wire]) => wire) };
|
|
70270
|
+
}
|
|
70271
|
+
const resolved = resolveV2Fields(config);
|
|
70272
|
+
for (const [wire, key] of exports2.V2_WIRE_FIELDS) {
|
|
70273
|
+
const v = resolved[key];
|
|
70274
|
+
if (typeof v === "string" && v.length > 0)
|
|
70275
|
+
fields[wire] = v;
|
|
70276
|
+
else
|
|
70277
|
+
absent.push(wire);
|
|
70278
|
+
}
|
|
70279
|
+
return { fields, absent };
|
|
70280
|
+
}
|
|
70092
70281
|
function isExecutionGrantEnabled(config) {
|
|
70093
70282
|
return !!(config && config.executionGrant && config.executionGrant.enabled === true);
|
|
70094
70283
|
}
|
|
@@ -70163,6 +70352,8 @@ var require_guard = __commonJS({
|
|
|
70163
70352
|
var monitoring_delivery_js_1 = require_monitoring_delivery();
|
|
70164
70353
|
var monitoring_attestation_js_1 = require_monitoring_attestation2();
|
|
70165
70354
|
var policy_js_1 = require_policy2();
|
|
70355
|
+
var deny_remedy_js_1 = require_deny_remedy();
|
|
70356
|
+
var next_agent_step_js_1 = require_next_agent_step();
|
|
70166
70357
|
var execution_grant_js_1 = require_execution_grant2();
|
|
70167
70358
|
var breakers = /* @__PURE__ */ new WeakMap();
|
|
70168
70359
|
var nowMs = () => Date.now();
|
|
@@ -70333,7 +70524,7 @@ var require_guard = __commonJS({
|
|
|
70333
70524
|
function coverageOutcomeFieldsFrom(s) {
|
|
70334
70525
|
return s.coverageObserved ? { coverage_observed: s.coverageObserved } : {};
|
|
70335
70526
|
}
|
|
70336
|
-
function blocked(config, verdict, preflighted, freshness, conditional_write, monitoring_delivery, monitoring_attestation, grantObs) {
|
|
70527
|
+
function blocked(config, verdict, preflighted, freshness, conditional_write, monitoring_delivery, monitoring_attestation, grantObs, call) {
|
|
70337
70528
|
const commit_observation = {
|
|
70338
70529
|
status: "not_observed",
|
|
70339
70530
|
observed_at: iso(),
|
|
@@ -70341,6 +70532,15 @@ var require_guard = __commonJS({
|
|
|
70341
70532
|
};
|
|
70342
70533
|
const base = { executionAttempted: false, executed: false, enforced: false, verdict, preflighted };
|
|
70343
70534
|
const cov = coverageSnap(config);
|
|
70535
|
+
const cause = "cause" in verdict ? verdict.cause : null;
|
|
70536
|
+
const nextStep = "envelope" in verdict && "receiptVerified" in verdict && verdict.receiptVerified === true ? (0, next_agent_step_js_1.readNextAgentStep)(verdict.envelope) : null;
|
|
70537
|
+
const remedy = call ? (0, deny_remedy_js_1.buildDenyRemedy)({
|
|
70538
|
+
error: (0, deny_remedy_js_1.denyErrorForReason)(cause),
|
|
70539
|
+
target: call.toolName || null,
|
|
70540
|
+
// The guard's own input fingerprint, already sha256:<hex>.
|
|
70541
|
+
fingerprint: fingerprint(call),
|
|
70542
|
+
observed: { cause, resolution: "resolution" in verdict ? verdict.resolution : null }
|
|
70543
|
+
}) : null;
|
|
70344
70544
|
const out = {
|
|
70345
70545
|
...base,
|
|
70346
70546
|
proof: (0, execution_proof_js_1.buildExecutionProof)({
|
|
@@ -70357,7 +70557,9 @@ var require_guard = __commonJS({
|
|
|
70357
70557
|
...monitoring_delivery ? { monitoring_delivery } : {},
|
|
70358
70558
|
...monitoring_attestation ? { monitoring_attestation } : {},
|
|
70359
70559
|
...coverageOutcomeFieldsFrom(cov),
|
|
70360
|
-
...grantObs ? { execution_grant: grantObs } : {}
|
|
70560
|
+
...grantObs ? { execution_grant: grantObs } : {},
|
|
70561
|
+
...remedy ? { remedy } : {},
|
|
70562
|
+
...nextStep ? { next_step: nextStep } : {}
|
|
70361
70563
|
};
|
|
70362
70564
|
return attachPolicyPresence(out, config);
|
|
70363
70565
|
}
|
|
@@ -70565,7 +70767,7 @@ var require_guard = __commonJS({
|
|
|
70565
70767
|
const v = unavailableVerdict({ cause: "MISSING_ARTIFACT_CONTENT", failPolicy, resolution: "CLOSED", action: "STOP" }, count);
|
|
70566
70768
|
const { basis } = freshnessFor(config, redacted, fctx, detection.artifacts);
|
|
70567
70769
|
const { basis: cw } = conditionalWriteFor(config, redacted, cwctx, detection.artifacts);
|
|
70568
|
-
return blocked(config, v, false, basis, cw);
|
|
70770
|
+
return blocked(config, v, false, basis, cw, void 0, void 0, void 0, redacted);
|
|
70569
70771
|
}
|
|
70570
70772
|
if (failPolicy === "lkg" && !config.lkg) {
|
|
70571
70773
|
breakerRecord(config);
|
|
@@ -70589,6 +70791,20 @@ var require_guard = __commonJS({
|
|
|
70589
70791
|
request.include_execution_grant = true;
|
|
70590
70792
|
if (nonceRes.nonce)
|
|
70591
70793
|
request.state_nonce = nonceRes.nonce;
|
|
70794
|
+
const wire = (0, execution_grant_js_1.v2WireFields)(config);
|
|
70795
|
+
if (config.executionGrant?.grantVersion === "v2") {
|
|
70796
|
+
request.grant_version = "v2";
|
|
70797
|
+
for (const [k, v] of Object.entries(wire.fields))
|
|
70798
|
+
request[k] = v;
|
|
70799
|
+
}
|
|
70800
|
+
if (config.executionGrant?.grantVersion === "v2") {
|
|
70801
|
+
grantObs = {
|
|
70802
|
+
...grantObs,
|
|
70803
|
+
grant_version: "v2",
|
|
70804
|
+
v2_fields_sent: Object.keys(wire.fields),
|
|
70805
|
+
v2_fields_absent: wire.absent
|
|
70806
|
+
};
|
|
70807
|
+
}
|
|
70592
70808
|
}
|
|
70593
70809
|
const cap = config.maxPayloadBytes ?? 1e6;
|
|
70594
70810
|
if (Buffer.byteLength(JSON.stringify(request), "utf8") > cap) {
|
|
@@ -70605,14 +70821,14 @@ var require_guard = __commonJS({
|
|
|
70605
70821
|
if (pf.integrity) {
|
|
70606
70822
|
emit(config, { type: "breaker_tripped", at: iso(), cause: pf.cause });
|
|
70607
70823
|
const v2 = unavailableVerdict({ cause: pf.cause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
|
|
70608
|
-
return blocked(config, v2, false, basis, cw, void 0, void 0, grantObs);
|
|
70824
|
+
return blocked(config, v2, false, basis, cw, void 0, void 0, grantObs, redacted);
|
|
70609
70825
|
}
|
|
70610
70826
|
const availCause = pf.cause;
|
|
70611
70827
|
if (grantObs && grantObs.requested) {
|
|
70612
70828
|
if (breakerTripped(config))
|
|
70613
70829
|
emit(config, { type: "breaker_tripped", at: iso(), cause: availCause });
|
|
70614
70830
|
const v2 = unavailableVerdict({ cause: availCause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
|
|
70615
|
-
return blocked(config, v2, false, basis, cw, void 0, void 0, grantObs);
|
|
70831
|
+
return blocked(config, v2, false, basis, cw, void 0, void 0, grantObs, redacted);
|
|
70616
70832
|
}
|
|
70617
70833
|
if (failPolicy === "open" && !breakerTripped(config)) {
|
|
70618
70834
|
emit(config, { type: "preflight_unavailable", at: iso(), cause: availCause, action: "CONTINUE" });
|
|
@@ -70630,7 +70846,7 @@ var require_guard = __commonJS({
|
|
|
70630
70846
|
if (breakerTripped(config))
|
|
70631
70847
|
emit(config, { type: "breaker_tripped", at: iso(), cause: availCause });
|
|
70632
70848
|
const v = unavailableVerdict({ cause: availCause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
|
|
70633
|
-
return blocked(config, v, false, basis, cw, void 0, void 0, grantObs);
|
|
70849
|
+
return blocked(config, v, false, basis, cw, void 0, void 0, grantObs, redacted);
|
|
70634
70850
|
}
|
|
70635
70851
|
const rd = (0, read_decision_js_1.readDecision)(pf.response);
|
|
70636
70852
|
if (rd.reason === "EXECUTION_ACTION_UNRECOGNISED") {
|
|
@@ -70670,7 +70886,7 @@ var require_guard = __commonJS({
|
|
|
70670
70886
|
if (gate.verdict === "block-strict") {
|
|
70671
70887
|
const { basis } = freshnessFor(config, redacted, fctx, detection.artifacts);
|
|
70672
70888
|
const { basis: cw } = conditionalWriteFor(config, redacted, cwctx, detection.artifacts);
|
|
70673
|
-
return gate.decision === "BLOCK" ? blocked(config, { kind: "BLOCK", action: "STOP", envelope, receiptVerified }, true, basis, cw, void 0, void 0, grantObs) : blocked(config, { kind: "APPROVAL", action: "REQUEST_APPROVAL", envelope, receiptVerified }, true, basis, cw, void 0, void 0, grantObs);
|
|
70889
|
+
return gate.decision === "BLOCK" ? blocked(config, { kind: "BLOCK", action: "STOP", envelope, receiptVerified }, true, basis, cw, void 0, void 0, grantObs, redacted) : blocked(config, { kind: "APPROVAL", action: "REQUEST_APPROVAL", envelope, receiptVerified }, true, basis, cw, void 0, void 0, grantObs, redacted);
|
|
70674
70890
|
}
|
|
70675
70891
|
const kind = gate.kind;
|
|
70676
70892
|
if (grantObs && grantObs.requested) {
|
|
@@ -70816,7 +71032,7 @@ var require_guard = __commonJS({
|
|
|
70816
71032
|
const v = unavailableVerdict({ cause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
|
|
70817
71033
|
const { basis } = freshnessFor(config, redacted, fctx, arts);
|
|
70818
71034
|
const { basis: cw } = conditionalWriteFor(config, redacted, cwctx, arts);
|
|
70819
|
-
return blocked(config, v, false, basis, cw, monitoring_delivery, monitoring_attestation, grantObs);
|
|
71035
|
+
return blocked(config, v, false, basis, cw, monitoring_delivery, monitoring_attestation, grantObs, redacted);
|
|
70820
71036
|
}
|
|
70821
71037
|
function isExpired(envelope) {
|
|
70822
71038
|
const exp = envelope.expires_at;
|
|
@@ -73407,6 +73623,7 @@ var require_deploy_receipt_token = __commonJS({
|
|
|
73407
73623
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
73408
73624
|
exports2.CHAIN_SIGNING_PREFIX = void 0;
|
|
73409
73625
|
exports2.verifyDeployReceiptToken = verifyDeployReceiptToken;
|
|
73626
|
+
var next_agent_step_js_1 = require_next_agent_step();
|
|
73410
73627
|
var node_crypto_1 = require("node:crypto");
|
|
73411
73628
|
var sdk_1 = require_cjs3();
|
|
73412
73629
|
var receipt_binding_js_1 = require_receipt_binding();
|
|
@@ -73427,6 +73644,31 @@ var require_deploy_receipt_token = __commonJS({
|
|
|
73427
73644
|
}
|
|
73428
73645
|
return v1;
|
|
73429
73646
|
}
|
|
73647
|
+
function deriveKeyWithdrawalStatus(ts, keyMeta) {
|
|
73648
|
+
const KNOWN_STATUSES = ["active", "retired", "revoked", null];
|
|
73649
|
+
if (!KNOWN_STATUSES.includes(keyMeta.status))
|
|
73650
|
+
return "UNKNOWN_KEY_STATUS";
|
|
73651
|
+
if (typeof keyMeta.revoked_at === "string" && keyMeta.revoked_at.length > 0)
|
|
73652
|
+
return "KEY_REVOKED";
|
|
73653
|
+
if (typeof keyMeta.retired_at === "string" && keyMeta.retired_at.length > 0 && ts) {
|
|
73654
|
+
const issued = Date.parse(ts);
|
|
73655
|
+
const retired = Date.parse(keyMeta.retired_at);
|
|
73656
|
+
if (Number.isFinite(issued) && Number.isFinite(retired) && issued >= retired) {
|
|
73657
|
+
return "KEY_RETIRED_AFTER_SIGNING";
|
|
73658
|
+
}
|
|
73659
|
+
}
|
|
73660
|
+
if (keyMeta.status === "revoked") {
|
|
73661
|
+
const at = keyMeta.compromised_at;
|
|
73662
|
+
if (typeof at !== "string" || at.length === 0)
|
|
73663
|
+
return "REVOKED_KEY_UNDECIDABLE";
|
|
73664
|
+
const boundary = Date.parse(at);
|
|
73665
|
+
const issued = typeof ts === "string" ? Date.parse(ts) : NaN;
|
|
73666
|
+
if (!Number.isFinite(boundary) || !Number.isFinite(issued))
|
|
73667
|
+
return "REVOKED_KEY_UNDECIDABLE";
|
|
73668
|
+
return issued >= boundary ? "REVOKED_KEY" : "REVOKED_KEY_UNDECIDABLE";
|
|
73669
|
+
}
|
|
73670
|
+
return null;
|
|
73671
|
+
}
|
|
73430
73672
|
function isIssueTimeWithinKeyWindow(ts, keyMeta) {
|
|
73431
73673
|
if (!keyMeta || keyMeta.status === "active")
|
|
73432
73674
|
return true;
|
|
@@ -73451,6 +73693,12 @@ var require_deploy_receipt_token = __commonJS({
|
|
|
73451
73693
|
return false;
|
|
73452
73694
|
return true;
|
|
73453
73695
|
}
|
|
73696
|
+
function optionalString(source, field) {
|
|
73697
|
+
if (!source || typeof source !== "object")
|
|
73698
|
+
return null;
|
|
73699
|
+
const v = source[field];
|
|
73700
|
+
return typeof v === "string" && v.length > 0 ? v : null;
|
|
73701
|
+
}
|
|
73454
73702
|
function resolveKey(kid, registry, pinnedKeyPem) {
|
|
73455
73703
|
if (typeof pinnedKeyPem === "string" && pinnedKeyPem.trim().length > 0) {
|
|
73456
73704
|
try {
|
|
@@ -73458,7 +73706,9 @@ var require_deploy_receipt_token = __commonJS({
|
|
|
73458
73706
|
publicKey: (0, node_crypto_1.createPublicKey)(pinnedKeyPem),
|
|
73459
73707
|
status: "active",
|
|
73460
73708
|
valid_from: null,
|
|
73461
|
-
retired_at: null
|
|
73709
|
+
retired_at: null,
|
|
73710
|
+
revoked_at: null,
|
|
73711
|
+
compromised_at: null
|
|
73462
73712
|
};
|
|
73463
73713
|
} catch {
|
|
73464
73714
|
return null;
|
|
@@ -73473,9 +73723,11 @@ var require_deploy_receipt_token = __commonJS({
|
|
|
73473
73723
|
try {
|
|
73474
73724
|
return {
|
|
73475
73725
|
publicKey: (0, node_crypto_1.createPublicKey)(entry.public_key_pem),
|
|
73476
|
-
status: entry.status === "
|
|
73726
|
+
status: typeof entry.status === "string" ? entry.status : null,
|
|
73477
73727
|
valid_from: entry.valid_from || null,
|
|
73478
|
-
retired_at: entry.retired_at || null
|
|
73728
|
+
retired_at: entry.retired_at || null,
|
|
73729
|
+
revoked_at: optionalString(entry, "revoked_at"),
|
|
73730
|
+
compromised_at: optionalString(entry, "compromised_at")
|
|
73479
73731
|
};
|
|
73480
73732
|
} catch {
|
|
73481
73733
|
return null;
|
|
@@ -73504,7 +73756,12 @@ var require_deploy_receipt_token = __commonJS({
|
|
|
73504
73756
|
bound_artifact_id: artifact == null ? null : String(artifact),
|
|
73505
73757
|
verdict_fingerprint: typeof envelope.fingerprint === "string" ? envelope.fingerprint : typeof payload.fp === "string" ? payload.fp : void 0,
|
|
73506
73758
|
body_hash: typeof payload.bh === "string" ? payload.bh : void 0,
|
|
73507
|
-
target_id: envelope.target_id == null ? void 0 : String(envelope.target_id)
|
|
73759
|
+
target_id: envelope.target_id == null ? void 0 : String(envelope.target_id),
|
|
73760
|
+
// Read from the envelope the caller supplied. On the currently_authorized path the
|
|
73761
|
+
// body hash has already bound it; on the expired / retired-key paths the signature
|
|
73762
|
+
// was authentic too. Every path that did NOT authenticate returns through fail(),
|
|
73763
|
+
// which sets view: null — so this field cannot carry an unsigned step.
|
|
73764
|
+
next_agent_step: (0, next_agent_step_js_1.readNextAgentStep)(envelope)
|
|
73508
73765
|
};
|
|
73509
73766
|
}
|
|
73510
73767
|
function verifyDeployReceiptToken(input, _intended = {}, nowMs) {
|
|
@@ -73549,6 +73806,14 @@ var require_deploy_receipt_token = __commonJS({
|
|
|
73549
73806
|
return fail("INVALID_SIGNATURE", "invalid_signature", { payload, authz_reason: "delimiter_in_field" });
|
|
73550
73807
|
}
|
|
73551
73808
|
}
|
|
73809
|
+
const withdrawn = deriveKeyWithdrawalStatus(typeof payload.ts === "string" ? payload.ts : void 0, resolved);
|
|
73810
|
+
if (withdrawn) {
|
|
73811
|
+
return fail(withdrawn, withdrawn === "UNKNOWN_KEY_STATUS" ? "unknown_key_status" : "revoked_key", {
|
|
73812
|
+
payload,
|
|
73813
|
+
authz_reason: withdrawn.toLowerCase(),
|
|
73814
|
+
key_status: withdrawn === "UNKNOWN_KEY_STATUS" ? "unknown" : "revoked"
|
|
73815
|
+
});
|
|
73816
|
+
}
|
|
73552
73817
|
if (resolved.status === "retired") {
|
|
73553
73818
|
if (!isIssueTimeWithinKeyWindow(typeof payload.ts === "string" ? payload.ts : void 0, resolved)) {
|
|
73554
73819
|
return fail("INVALID_SIGNATURE", "invalid_signature", { payload, authz_reason: "retired_key_outside_window" });
|
|
@@ -73629,6 +73894,7 @@ var require_deploy_gate = __commonJS({
|
|
|
73629
73894
|
exports2.isVerifiedDeployReceiptView = isVerifiedDeployReceiptView;
|
|
73630
73895
|
exports2.deployGate = deployGate;
|
|
73631
73896
|
var deploy_receipt_token_js_1 = require_deploy_receipt_token();
|
|
73897
|
+
var next_agent_step_js_1 = require_next_agent_step();
|
|
73632
73898
|
exports2.DEPLOY_RECEIPT_VIEW_SPEC = "deploy-receipt-view.v1";
|
|
73633
73899
|
function asVerifiedDeployReceiptView(view, verify_status = "VERIFIED_CURRENT") {
|
|
73634
73900
|
return {
|
|
@@ -73690,16 +73956,21 @@ var require_deploy_gate = __commonJS({
|
|
|
73690
73956
|
bound_artifact_id: r && r.bound_artifact_id != null ? norm(r.bound_artifact_id) : null,
|
|
73691
73957
|
operation: r && r.operation != null ? String(r.operation) : null
|
|
73692
73958
|
});
|
|
73693
|
-
const
|
|
73694
|
-
|
|
73695
|
-
|
|
73696
|
-
|
|
73697
|
-
|
|
73698
|
-
|
|
73699
|
-
|
|
73700
|
-
|
|
73701
|
-
|
|
73702
|
-
|
|
73959
|
+
const nextStepOf = (r) => verification.mode === "token" ? (0, next_agent_step_js_1.readNextAgentStep)(r) : null;
|
|
73960
|
+
const deny = (state, reason) => {
|
|
73961
|
+
const step = nextStepOf(receipt);
|
|
73962
|
+
return {
|
|
73963
|
+
deploy_allowed: false,
|
|
73964
|
+
state,
|
|
73965
|
+
reason,
|
|
73966
|
+
enforcement_state,
|
|
73967
|
+
inescapable_deploy: false,
|
|
73968
|
+
residuals: [],
|
|
73969
|
+
detail: detailOf(receipt),
|
|
73970
|
+
verification,
|
|
73971
|
+
...step ? { next_step: step } : {}
|
|
73972
|
+
};
|
|
73973
|
+
};
|
|
73703
73974
|
if (!target.environment || String(target.environment).trim() === "" || !target.artifact_id || String(target.artifact_id).trim() === "") {
|
|
73704
73975
|
return deny(allowPending ? "pending" : "failure", "inputs_incomplete");
|
|
73705
73976
|
}
|
|
@@ -74040,18 +74311,168 @@ var require_coverage_report = __commonJS({
|
|
|
74040
74311
|
}
|
|
74041
74312
|
});
|
|
74042
74313
|
|
|
74314
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/posture-receipt.js
|
|
74315
|
+
var require_posture_receipt = __commonJS({
|
|
74316
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/posture-receipt.js"(exports2) {
|
|
74317
|
+
"use strict";
|
|
74318
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
74319
|
+
exports2.POSTURE_CLOCK_SKEW_TOLERANCE_MS = exports2.POSTURE_RECEIPT_V = void 0;
|
|
74320
|
+
exports2.verifyPostureReceipt = verifyPostureReceipt;
|
|
74321
|
+
var node_crypto_1 = require("node:crypto");
|
|
74322
|
+
exports2.POSTURE_RECEIPT_V = "cr.posture.receipt.v1";
|
|
74323
|
+
exports2.POSTURE_CLOCK_SKEW_TOLERANCE_MS = 5e3;
|
|
74324
|
+
function resolvePostureKey(kid, registry, pinnedKeyPem) {
|
|
74325
|
+
if (typeof pinnedKeyPem === "string" && pinnedKeyPem.trim().length > 0) {
|
|
74326
|
+
try {
|
|
74327
|
+
return { ok: true, key: (0, node_crypto_1.createPublicKey)(pinnedKeyPem) };
|
|
74328
|
+
} catch {
|
|
74329
|
+
return { ok: false, status: "POSTURE_UNKNOWN_KEY" };
|
|
74330
|
+
}
|
|
74331
|
+
}
|
|
74332
|
+
if (!registry || !Array.isArray(registry.keys) || !kid) {
|
|
74333
|
+
return { ok: false, status: "POSTURE_UNKNOWN_KEY" };
|
|
74334
|
+
}
|
|
74335
|
+
const matches = registry.keys.filter((k) => k && k.kid === kid && typeof k.public_key_pem === "string");
|
|
74336
|
+
if (matches.length === 0)
|
|
74337
|
+
return { ok: false, status: "POSTURE_UNKNOWN_KEY" };
|
|
74338
|
+
const entry = matches.find((k) => k.status === "active");
|
|
74339
|
+
if (!entry)
|
|
74340
|
+
return { ok: false, status: "POSTURE_REVOKED_KEY" };
|
|
74341
|
+
try {
|
|
74342
|
+
return { ok: true, key: (0, node_crypto_1.createPublicKey)(entry.public_key_pem) };
|
|
74343
|
+
} catch {
|
|
74344
|
+
return { ok: false, status: "POSTURE_UNKNOWN_KEY" };
|
|
74345
|
+
}
|
|
74346
|
+
}
|
|
74347
|
+
var fail = (status, reason, extra = {}) => ({ valid: false, status, reason, ...extra });
|
|
74348
|
+
function verifyPostureReceipt(token, input = {}) {
|
|
74349
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
74350
|
+
return fail("POSTURE_MALFORMED", "malformed_structure");
|
|
74351
|
+
}
|
|
74352
|
+
const seg = token.split("|");
|
|
74353
|
+
if (seg.length !== 4 || seg[0] !== exports2.POSTURE_RECEIPT_V || seg.some((x) => !x)) {
|
|
74354
|
+
return fail("POSTURE_MALFORMED", "malformed_structure");
|
|
74355
|
+
}
|
|
74356
|
+
let preimageBytes;
|
|
74357
|
+
try {
|
|
74358
|
+
preimageBytes = Buffer.from(seg[2], "base64url");
|
|
74359
|
+
if (preimageBytes.length === 0)
|
|
74360
|
+
throw new Error("empty");
|
|
74361
|
+
} catch {
|
|
74362
|
+
return fail("POSTURE_MALFORMED", "bad_preimage");
|
|
74363
|
+
}
|
|
74364
|
+
const resolved = resolvePostureKey(seg[1], input.registry, input.pinnedKeyPem);
|
|
74365
|
+
if (!resolved.ok) {
|
|
74366
|
+
return fail(resolved.status, resolved.status === "POSTURE_REVOKED_KEY" ? "kid_revoked" : "unknown_kid");
|
|
74367
|
+
}
|
|
74368
|
+
const key = resolved.key;
|
|
74369
|
+
let sigOk = false;
|
|
74370
|
+
try {
|
|
74371
|
+
sigOk = (0, node_crypto_1.verify)(null, preimageBytes, key, Buffer.from(seg[3], "base64url"));
|
|
74372
|
+
} catch {
|
|
74373
|
+
return fail("POSTURE_INVALID_SIGNATURE", "signature_error");
|
|
74374
|
+
}
|
|
74375
|
+
if (!sigOk)
|
|
74376
|
+
return fail("POSTURE_INVALID_SIGNATURE", "signature_mismatch");
|
|
74377
|
+
let payload;
|
|
74378
|
+
try {
|
|
74379
|
+
payload = JSON.parse(preimageBytes.toString("utf8"));
|
|
74380
|
+
} catch {
|
|
74381
|
+
return fail("POSTURE_MALFORMED", "bad_json");
|
|
74382
|
+
}
|
|
74383
|
+
if (!payload || typeof payload !== "object") {
|
|
74384
|
+
return fail("POSTURE_MALFORMED", "bad_json");
|
|
74385
|
+
}
|
|
74386
|
+
if (payload.verdict !== "PASS") {
|
|
74387
|
+
return fail("POSTURE_FAIL", "posture_verdict_not_pass", { payload });
|
|
74388
|
+
}
|
|
74389
|
+
if (typeof payload.executor_kid === "string" && payload.executor_kid.length > 0 && payload.executor_kid !== seg[1]) {
|
|
74390
|
+
return fail("POSTURE_UNBOUND", "kid_mismatch", { payload });
|
|
74391
|
+
}
|
|
74392
|
+
if (Object.prototype.hasOwnProperty.call(payload, "v") && payload.v != null && payload.v !== exports2.POSTURE_RECEIPT_V) {
|
|
74393
|
+
return fail("POSTURE_MALFORMED", "body_version_mismatch", { payload });
|
|
74394
|
+
}
|
|
74395
|
+
if (typeof input.expectedDeploymentId === "string" && input.expectedDeploymentId.length > 0) {
|
|
74396
|
+
if (payload.deployment_id !== input.expectedDeploymentId) {
|
|
74397
|
+
return fail("POSTURE_UNBOUND", "deployment_id_mismatch", { payload });
|
|
74398
|
+
}
|
|
74399
|
+
}
|
|
74400
|
+
const bound = [];
|
|
74401
|
+
const notBound = [];
|
|
74402
|
+
const tuple = [
|
|
74403
|
+
["executor_id", input.expectedExecutorId, "executor_id"],
|
|
74404
|
+
["adapter_id", input.expectedAdapterId, "adapter_id"],
|
|
74405
|
+
["target_uri", input.expectedTargetUri, "target_uri"],
|
|
74406
|
+
["policy_hash", input.expectedPolicyHash, "policy_hash"]
|
|
74407
|
+
];
|
|
74408
|
+
for (const [field, expected, label] of tuple) {
|
|
74409
|
+
if (typeof expected !== "string" || expected.length === 0) {
|
|
74410
|
+
notBound.push({
|
|
74411
|
+
field: label,
|
|
74412
|
+
reason: "the caller did not state an expected value, so this verification did not check it"
|
|
74413
|
+
});
|
|
74414
|
+
continue;
|
|
74415
|
+
}
|
|
74416
|
+
const actual = payload[field];
|
|
74417
|
+
if (typeof actual !== "string" || actual.length === 0) {
|
|
74418
|
+
return fail("POSTURE_UNBOUND", `${label}_absent`, { payload, bound, not_bound: notBound });
|
|
74419
|
+
}
|
|
74420
|
+
if (actual !== expected) {
|
|
74421
|
+
return fail("POSTURE_UNBOUND", `${label}_mismatch`, { payload, bound, not_bound: notBound });
|
|
74422
|
+
}
|
|
74423
|
+
bound.push(label);
|
|
74424
|
+
}
|
|
74425
|
+
let ageMs;
|
|
74426
|
+
if (typeof input.maxAgeMs === "number" && Number.isFinite(input.maxAgeMs)) {
|
|
74427
|
+
const measured = Date.parse(String(payload.measured_at));
|
|
74428
|
+
if (Number.isNaN(measured)) {
|
|
74429
|
+
return fail("POSTURE_STALE", "measured_at_unparseable", { payload });
|
|
74430
|
+
}
|
|
74431
|
+
const now = (input.now || (() => Date.now()))();
|
|
74432
|
+
if (!Number.isFinite(now)) {
|
|
74433
|
+
return fail("POSTURE_STALE", "now_unparseable", { payload });
|
|
74434
|
+
}
|
|
74435
|
+
ageMs = now - measured;
|
|
74436
|
+
if (!Number.isFinite(ageMs)) {
|
|
74437
|
+
return fail("POSTURE_STALE", "measured_at_unparseable", { payload });
|
|
74438
|
+
}
|
|
74439
|
+
if (ageMs < -exports2.POSTURE_CLOCK_SKEW_TOLERANCE_MS) {
|
|
74440
|
+
return fail("POSTURE_STALE", "measured_at_in_future", { payload, age_ms: ageMs });
|
|
74441
|
+
}
|
|
74442
|
+
if (ageMs > input.maxAgeMs) {
|
|
74443
|
+
return fail("POSTURE_STALE", "outside_freshness_window", { payload, age_ms: ageMs });
|
|
74444
|
+
}
|
|
74445
|
+
}
|
|
74446
|
+
return {
|
|
74447
|
+
valid: true,
|
|
74448
|
+
status: "POSTURE_PASS",
|
|
74449
|
+
reason: null,
|
|
74450
|
+
payload,
|
|
74451
|
+
...ageMs === void 0 ? {} : { age_ms: ageMs },
|
|
74452
|
+
// What this PASS actually proved about the credential boundary — and what
|
|
74453
|
+
// it did not. A caller must not have to infer the difference.
|
|
74454
|
+
bound,
|
|
74455
|
+
not_bound: notBound
|
|
74456
|
+
};
|
|
74457
|
+
}
|
|
74458
|
+
}
|
|
74459
|
+
});
|
|
74460
|
+
|
|
74043
74461
|
// node_modules/@coderifts/agent-guard/dist/cjs/atomic-profile.js
|
|
74044
74462
|
var require_atomic_profile = __commonJS({
|
|
74045
74463
|
"node_modules/@coderifts/agent-guard/dist/cjs/atomic-profile.js"(exports2) {
|
|
74046
74464
|
"use strict";
|
|
74047
74465
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
74048
|
-
exports2.ATOMIC_INVARIANTS = exports2.ATOMIC_PROFILE_UNSATISFIED = exports2.GUARD_ATOMIC_WIRE_VALUE = exports2.PROFILE_ENFORCING_ATOMIC_V1 = void 0;
|
|
74466
|
+
exports2.CREDENTIAL_BOUNDARY_BARE_REJECTED = exports2.ATOMIC_V2_MAX_AGE_MS_CAP = exports2.ATOMIC_INVARIANTS = exports2.ATOMIC_PROFILE_UNSATISFIED = exports2.GUARD_ATOMIC_WIRE_VALUE = exports2.PROFILE_ENFORCING_ATOMIC_V2 = exports2.PROFILE_ENFORCING_ATOMIC_V1 = void 0;
|
|
74049
74467
|
exports2.createMutatorRegister = createMutatorRegister;
|
|
74050
74468
|
exports2.isEnforcingAtomic = isEnforcingAtomic;
|
|
74469
|
+
exports2.isEnforcingAtomicV2 = isEnforcingAtomicV2;
|
|
74051
74470
|
exports2.atomicConstructionProblems = atomicConstructionProblems;
|
|
74052
74471
|
exports2.throwAtomicUnsatisfied = throwAtomicUnsatisfied;
|
|
74053
74472
|
exports2.atomicOutcome = atomicOutcome;
|
|
74473
|
+
var posture_receipt_js_1 = require_posture_receipt();
|
|
74054
74474
|
exports2.PROFILE_ENFORCING_ATOMIC_V1 = "ENFORCING_ATOMIC_V1";
|
|
74475
|
+
exports2.PROFILE_ENFORCING_ATOMIC_V2 = "ENFORCING_ATOMIC_V2";
|
|
74055
74476
|
exports2.GUARD_ATOMIC_WIRE_VALUE = "ENFORCING_ATOMIC";
|
|
74056
74477
|
exports2.ATOMIC_PROFILE_UNSATISFIED = "ATOMIC_PROFILE_UNSATISFIED";
|
|
74057
74478
|
exports2.ATOMIC_INVARIANTS = Object.freeze([
|
|
@@ -74087,8 +74508,13 @@ var require_atomic_profile = __commonJS({
|
|
|
74087
74508
|
return api;
|
|
74088
74509
|
}
|
|
74089
74510
|
function isEnforcingAtomic(profile) {
|
|
74090
|
-
return profile === "ENFORCING_ATOMIC" || profile === exports2.PROFILE_ENFORCING_ATOMIC_V1;
|
|
74511
|
+
return profile === "ENFORCING_ATOMIC" || profile === exports2.PROFILE_ENFORCING_ATOMIC_V1 || profile === exports2.PROFILE_ENFORCING_ATOMIC_V2;
|
|
74091
74512
|
}
|
|
74513
|
+
function isEnforcingAtomicV2(profile) {
|
|
74514
|
+
return profile === exports2.PROFILE_ENFORCING_ATOMIC_V2;
|
|
74515
|
+
}
|
|
74516
|
+
exports2.ATOMIC_V2_MAX_AGE_MS_CAP = 864e5;
|
|
74517
|
+
exports2.CREDENTIAL_BOUNDARY_BARE_REJECTED = "credential_boundary: a verified cr.posture.receipt.v1 is required; a bare assertion is no longer accepted. ENFORCING_ATOMIC_V1 still accepts the bare form and is frozen \u2014 move to _V2 to get this check.";
|
|
74092
74518
|
function atomicConstructionProblems(input) {
|
|
74093
74519
|
const problems = [];
|
|
74094
74520
|
const grant = input.executionGrant;
|
|
@@ -74125,6 +74551,42 @@ var require_atomic_profile = __commonJS({
|
|
|
74125
74551
|
if (input.credentialBoundary !== true && typeof input.credentialBoundary !== "object") {
|
|
74126
74552
|
problems.push("credential_boundary: credentialBoundary assertion required");
|
|
74127
74553
|
}
|
|
74554
|
+
if (isEnforcingAtomicV2(input.profile)) {
|
|
74555
|
+
const cb = input.credentialBoundary;
|
|
74556
|
+
if (cb === true || !cb || typeof cb !== "object" || typeof cb.postureReceipt !== "string") {
|
|
74557
|
+
problems.push(exports2.CREDENTIAL_BOUNDARY_BARE_REJECTED);
|
|
74558
|
+
} else if (!cb.registry && !cb.pinnedKeyPem) {
|
|
74559
|
+
problems.push("credential_boundary: credentialBoundary.registry or .pinnedKeyPem required \u2014 the posture receipt is verified against a caller-supplied key; this package never fetches one.");
|
|
74560
|
+
} else {
|
|
74561
|
+
const deploymentId = typeof cb.deploymentId === "string" ? cb.deploymentId : "";
|
|
74562
|
+
if (deploymentId.length === 0) {
|
|
74563
|
+
problems.push("credential_boundary: credentialBoundary.deploymentId required under ENFORCING_ATOMIC_V2 \u2014 the posture receipt must be bound to this deployment.");
|
|
74564
|
+
}
|
|
74565
|
+
const maxAgeMs = cb.maxAgeMs;
|
|
74566
|
+
const maxAgeOk = typeof maxAgeMs === "number" && Number.isFinite(maxAgeMs) && maxAgeMs > 0 && maxAgeMs <= exports2.ATOMIC_V2_MAX_AGE_MS_CAP;
|
|
74567
|
+
if (typeof maxAgeMs !== "number" || !Number.isFinite(maxAgeMs) || maxAgeMs <= 0) {
|
|
74568
|
+
problems.push("credential_boundary: credentialBoundary.maxAgeMs required under ENFORCING_ATOMIC_V2 \u2014 a finite positive freshness window; the receipt signs measured_at and no expires_at.");
|
|
74569
|
+
} else if (maxAgeMs > exports2.ATOMIC_V2_MAX_AGE_MS_CAP) {
|
|
74570
|
+
problems.push(`credential_boundary: credentialBoundary.maxAgeMs exceeds the ${exports2.ATOMIC_V2_MAX_AGE_MS_CAP}ms cap (24h). A larger window is not a freshness check.`);
|
|
74571
|
+
}
|
|
74572
|
+
if (deploymentId.length > 0 && maxAgeOk) {
|
|
74573
|
+
const r = (0, posture_receipt_js_1.verifyPostureReceipt)(cb.postureReceipt, {
|
|
74574
|
+
registry: cb.registry,
|
|
74575
|
+
pinnedKeyPem: cb.pinnedKeyPem,
|
|
74576
|
+
expectedDeploymentId: deploymentId,
|
|
74577
|
+
expectedExecutorId: input.executorId,
|
|
74578
|
+
expectedAdapterId: input.adapterId,
|
|
74579
|
+
expectedTargetUri: input.targetUri,
|
|
74580
|
+
expectedPolicyHash: input.policyHash,
|
|
74581
|
+
maxAgeMs,
|
|
74582
|
+
now: cb.now
|
|
74583
|
+
});
|
|
74584
|
+
if (!r.valid) {
|
|
74585
|
+
problems.push(`credential_boundary: posture receipt not verified \u2014 ${r.status} (${r.reason}). ` + (r.status === "POSTURE_STALE" ? "This is the caller-supplied freshness window (maxAgeMs), not a receipt-carried expiry: cr.posture.receipt.v1 signs measured_at and no expires_at." : r.status === "POSTURE_FAIL" ? "The signature verified; the posture did not. A signed FAIL is a drift artifact \u2014 the boundary regressed, the receipt is intact." : "Supply a posture receipt signed by a key in the registry, bound to this deployment_id, with verdict PASS."));
|
|
74586
|
+
}
|
|
74587
|
+
}
|
|
74588
|
+
}
|
|
74589
|
+
}
|
|
74128
74590
|
return problems;
|
|
74129
74591
|
}
|
|
74130
74592
|
function throwAtomicUnsatisfied(problems) {
|
|
@@ -74153,11 +74615,13 @@ var require_with_coderifts = __commonJS({
|
|
|
74153
74615
|
"node_modules/@coderifts/agent-guard/dist/cjs/with-coderifts.js"(exports2) {
|
|
74154
74616
|
"use strict";
|
|
74155
74617
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
74156
|
-
exports2.PROFILE_ENFORCING_ATOMIC_V1 = exports2.PROFILE_ENFORCING_STRICT_V1 = void 0;
|
|
74618
|
+
exports2.UNVERSIONED_PROFILE_NOTICE = exports2.PROFILE_ENFORCING_ATOMIC_V2 = exports2.PROFILE_ENFORCING_ATOMIC_V1 = exports2.PROFILE_ENFORCING_STRICT_V1 = void 0;
|
|
74157
74619
|
exports2.foldTableSettledCalls = foldTableSettledCalls;
|
|
74158
74620
|
exports2.guardedFractionAmongRoutes = guardedFractionAmongRoutes;
|
|
74621
|
+
exports2._resetUnversionedProfileNoticeForTest = _resetUnversionedProfileNoticeForTest;
|
|
74159
74622
|
exports2.withCodeRifts = withCodeRifts;
|
|
74160
74623
|
var tool_registry_js_1 = require_tool_registry();
|
|
74624
|
+
var execution_grant_js_1 = require_execution_grant2();
|
|
74161
74625
|
var coverage_observed_js_1 = require_coverage_observed();
|
|
74162
74626
|
var atomic_profile_js_1 = require_atomic_profile();
|
|
74163
74627
|
function foldTableSettledCalls(events) {
|
|
@@ -74185,9 +74649,13 @@ var require_with_coderifts = __commonJS({
|
|
|
74185
74649
|
Object.defineProperty(exports2, "PROFILE_ENFORCING_ATOMIC_V1", { enumerable: true, get: function() {
|
|
74186
74650
|
return atomic_profile_js_2.PROFILE_ENFORCING_ATOMIC_V1;
|
|
74187
74651
|
} });
|
|
74652
|
+
Object.defineProperty(exports2, "PROFILE_ENFORCING_ATOMIC_V2", { enumerable: true, get: function() {
|
|
74653
|
+
return atomic_profile_js_2.PROFILE_ENFORCING_ATOMIC_V2;
|
|
74654
|
+
} });
|
|
74188
74655
|
var ACCEPTED_PROFILES = Object.freeze([
|
|
74189
74656
|
"ENFORCING_STRICT_V1",
|
|
74190
74657
|
"ENFORCING_STRICT",
|
|
74658
|
+
"ENFORCING_ATOMIC_V2",
|
|
74191
74659
|
"ENFORCING_ATOMIC_V1",
|
|
74192
74660
|
"ENFORCING_ATOMIC"
|
|
74193
74661
|
]);
|
|
@@ -74211,6 +74679,19 @@ var require_with_coderifts = __commonJS({
|
|
|
74211
74679
|
function isEnforcingStrict(input) {
|
|
74212
74680
|
return input.profile === "ENFORCING_STRICT" || input.profile === exports2.PROFILE_ENFORCING_STRICT_V1;
|
|
74213
74681
|
}
|
|
74682
|
+
exports2.UNVERSIONED_PROFILE_NOTICE = "ENFORCING_STRICT is the unversioned spelling of ENFORCING_STRICT_V1; prefer the versioned name.";
|
|
74683
|
+
var noticedUnversionedProfile = false;
|
|
74684
|
+
function _resetUnversionedProfileNoticeForTest() {
|
|
74685
|
+
noticedUnversionedProfile = false;
|
|
74686
|
+
}
|
|
74687
|
+
function noticeUnversionedProfileOnce(profile) {
|
|
74688
|
+
if (profile !== "ENFORCING_STRICT")
|
|
74689
|
+
return;
|
|
74690
|
+
if (noticedUnversionedProfile)
|
|
74691
|
+
return;
|
|
74692
|
+
noticedUnversionedProfile = true;
|
|
74693
|
+
console.warn(exports2.UNVERSIONED_PROFILE_NOTICE);
|
|
74694
|
+
}
|
|
74214
74695
|
function enforcingStrictExecutionChainProblems(input) {
|
|
74215
74696
|
const grant = input.executionGrant;
|
|
74216
74697
|
const enabled = !!(grant && grant.enabled === true);
|
|
@@ -74441,6 +74922,7 @@ var require_with_coderifts = __commonJS({
|
|
|
74441
74922
|
if (!input || typeof input !== "object") {
|
|
74442
74923
|
throw new Error("withCodeRifts: input object is required");
|
|
74443
74924
|
}
|
|
74925
|
+
noticeUnversionedProfileOnce(input.profile);
|
|
74444
74926
|
const problems = [];
|
|
74445
74927
|
if (typeof input.operation !== "string" || input.operation.trim() === "") {
|
|
74446
74928
|
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)");
|
|
@@ -74465,16 +74947,21 @@ var require_with_coderifts = __commonJS({
|
|
|
74465
74947
|
problems.push(...enforcingStrictExecutionChainProblems(input));
|
|
74466
74948
|
}
|
|
74467
74949
|
if ((0, atomic_profile_js_1.isEnforcingAtomic)(input.profile)) {
|
|
74950
|
+
const v2 = (0, execution_grant_js_1.resolveV2Fields)(input);
|
|
74468
74951
|
const atomicProblems = (0, atomic_profile_js_1.atomicConstructionProblems)({
|
|
74469
74952
|
executionGrant: input.executionGrant,
|
|
74470
|
-
executorId:
|
|
74471
|
-
adapterId:
|
|
74472
|
-
targetUri:
|
|
74953
|
+
executorId: v2.executorId,
|
|
74954
|
+
adapterId: v2.adapterId,
|
|
74955
|
+
targetUri: v2.targetUri,
|
|
74956
|
+
// Previously never forwarded, so the posture verifier's policy_hash
|
|
74957
|
+
// binding could not fire no matter what the caller configured.
|
|
74958
|
+
policyHash: v2.policyHash,
|
|
74473
74959
|
executorAttestation: input.executorAttestation,
|
|
74474
74960
|
mutatorRegister: input.mutatorRegister,
|
|
74475
74961
|
casAdapter: input.casAdapter,
|
|
74476
74962
|
readBack: input.readBack,
|
|
74477
|
-
credentialBoundary: input.credentialBoundary
|
|
74963
|
+
credentialBoundary: input.credentialBoundary,
|
|
74964
|
+
profile: input.profile
|
|
74478
74965
|
});
|
|
74479
74966
|
if (atomicProblems.length > 0)
|
|
74480
74967
|
(0, atomic_profile_js_1.throwAtomicUnsatisfied)(atomicProblems);
|
|
@@ -74553,6 +75040,7 @@ var require_with_coderifts = __commonJS({
|
|
|
74553
75040
|
}
|
|
74554
75041
|
if (input.executionGrant !== void 0) {
|
|
74555
75042
|
guard.executionGrant = input.executionGrant;
|
|
75043
|
+
Object.assign(guard, (0, execution_grant_js_1.resolveV2Fields)(input));
|
|
74556
75044
|
}
|
|
74557
75045
|
const strict = isEnforcingStrict(input);
|
|
74558
75046
|
if (strict) {
|
|
@@ -75105,49 +75593,140 @@ var require_gemini = __commonJS({
|
|
|
75105
75593
|
}
|
|
75106
75594
|
});
|
|
75107
75595
|
|
|
75108
|
-
// node_modules/@coderifts/agent-guard/dist/cjs/
|
|
75109
|
-
var
|
|
75110
|
-
"node_modules/@coderifts/agent-guard/dist/cjs/
|
|
75596
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/adapters/langchain.js
|
|
75597
|
+
var require_langchain = __commonJS({
|
|
75598
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/adapters/langchain.js"(exports2) {
|
|
75111
75599
|
"use strict";
|
|
75112
75600
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
75113
|
-
exports2.
|
|
75114
|
-
exports2.
|
|
75115
|
-
exports2.
|
|
75116
|
-
|
|
75117
|
-
|
|
75118
|
-
|
|
75119
|
-
|
|
75120
|
-
|
|
75121
|
-
|
|
75122
|
-
|
|
75123
|
-
|
|
75124
|
-
|
|
75125
|
-
|
|
75126
|
-
|
|
75127
|
-
return
|
|
75128
|
-
if (table && typeof table === "object") {
|
|
75129
|
-
const bag = table;
|
|
75130
|
-
if (Array.isArray(bag.protected_tools) && bag.protected_tools.length > 0) {
|
|
75131
|
-
return bag.protected_tools;
|
|
75132
|
-
}
|
|
75133
|
-
if (Array.isArray(bag.tools)) {
|
|
75134
|
-
const withExecute = bag.tools.filter((t) => t && typeof t === "object" && typeof t.execute === "function");
|
|
75135
|
-
if (withExecute.length > 0)
|
|
75136
|
-
return withExecute;
|
|
75137
|
-
}
|
|
75601
|
+
exports2.LANGCHAIN_ARTIFACT_SPEC = void 0;
|
|
75602
|
+
exports2.defaultSerializeLangChainToolResult = defaultSerializeLangChainToolResult;
|
|
75603
|
+
exports2.bindLangChainToolOutcome = bindLangChainToolOutcome;
|
|
75604
|
+
var final_answer_proof_js_1 = require_final_answer_proof();
|
|
75605
|
+
var gate_refusal_js_1 = require_gate_refusal();
|
|
75606
|
+
function defaultSerializeLangChainToolResult(result) {
|
|
75607
|
+
if (typeof result === "string")
|
|
75608
|
+
return result;
|
|
75609
|
+
if (typeof result === "number" || typeof result === "boolean" || typeof result === "bigint" || result === null || result === void 0) {
|
|
75610
|
+
return String(result);
|
|
75611
|
+
}
|
|
75612
|
+
try {
|
|
75613
|
+
return JSON.stringify(result);
|
|
75614
|
+
} catch {
|
|
75615
|
+
return String(result);
|
|
75138
75616
|
}
|
|
75139
|
-
return [];
|
|
75140
75617
|
}
|
|
75141
|
-
|
|
75142
|
-
|
|
75143
|
-
|
|
75618
|
+
exports2.LANGCHAIN_ARTIFACT_SPEC = "coderifts-guard-artifact.v1";
|
|
75619
|
+
function bindLangChainToolOutcome(outcome, args) {
|
|
75620
|
+
const serialize = args.serialize ?? defaultSerializeLangChainToolResult;
|
|
75621
|
+
let body;
|
|
75622
|
+
if (outcome.executed === true) {
|
|
75623
|
+
body = serialize(outcome.result);
|
|
75624
|
+
} else if (outcome.executionAttempted === false) {
|
|
75625
|
+
body = (0, gate_refusal_js_1.formatGateRefusalBody)(outcome);
|
|
75626
|
+
} else {
|
|
75627
|
+
const err = "error" in outcome ? outcome.error : void 0;
|
|
75628
|
+
const kind = (0, gate_refusal_js_1.verdictKind)(outcome);
|
|
75629
|
+
body = `Tool execution failed after gate decision (verdict: ${kind}): ${(0, gate_refusal_js_1.formatGuardError)(err)}`;
|
|
75630
|
+
}
|
|
75631
|
+
const content = args.attachProof === false ? body : (0, final_answer_proof_js_1.attachProofToAgentResponse)(body, outcome.proof);
|
|
75632
|
+
const out = {
|
|
75633
|
+
content,
|
|
75634
|
+
artifact: {
|
|
75635
|
+
artifact_spec: exports2.LANGCHAIN_ARTIFACT_SPEC,
|
|
75636
|
+
final_answer_proof: outcome.proof,
|
|
75637
|
+
executed: outcome.executed === true,
|
|
75638
|
+
enforced: outcome.enforced === true,
|
|
75639
|
+
verdict: (0, gate_refusal_js_1.verdictKind)(outcome)
|
|
75640
|
+
},
|
|
75641
|
+
tool_call_id: args.tool_call_id
|
|
75642
|
+
};
|
|
75643
|
+
if (args.name != null && args.name !== "") {
|
|
75644
|
+
out.name = args.name;
|
|
75645
|
+
}
|
|
75646
|
+
return out;
|
|
75144
75647
|
}
|
|
75145
|
-
|
|
75648
|
+
}
|
|
75649
|
+
});
|
|
75650
|
+
|
|
75651
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/adapters/crewai.js
|
|
75652
|
+
var require_crewai = __commonJS({
|
|
75653
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/adapters/crewai.js"(exports2) {
|
|
75654
|
+
"use strict";
|
|
75655
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
75656
|
+
exports2.defaultSerializeCrewAIToolResult = defaultSerializeCrewAIToolResult;
|
|
75657
|
+
exports2.bindCrewAIToolOutcome = bindCrewAIToolOutcome;
|
|
75658
|
+
var final_answer_proof_js_1 = require_final_answer_proof();
|
|
75659
|
+
var gate_refusal_js_1 = require_gate_refusal();
|
|
75660
|
+
function defaultSerializeCrewAIToolResult(result) {
|
|
75661
|
+
if (typeof result === "string")
|
|
75662
|
+
return result;
|
|
75663
|
+
if (typeof result === "number" || typeof result === "boolean" || typeof result === "bigint" || result === null || result === void 0) {
|
|
75664
|
+
return String(result);
|
|
75665
|
+
}
|
|
75666
|
+
try {
|
|
75667
|
+
return JSON.stringify(result);
|
|
75668
|
+
} catch {
|
|
75669
|
+
return String(result);
|
|
75670
|
+
}
|
|
75671
|
+
}
|
|
75672
|
+
function bindCrewAIToolOutcome(outcome, args) {
|
|
75673
|
+
const serialize = args.serialize ?? defaultSerializeCrewAIToolResult;
|
|
75674
|
+
let body;
|
|
75675
|
+
let resultAsAnswer;
|
|
75676
|
+
if (outcome.executed === true) {
|
|
75677
|
+
body = serialize(outcome.result);
|
|
75678
|
+
resultAsAnswer = false;
|
|
75679
|
+
} else if (outcome.executionAttempted === false) {
|
|
75680
|
+
body = (0, gate_refusal_js_1.formatGateRefusalBody)(outcome);
|
|
75681
|
+
resultAsAnswer = true;
|
|
75682
|
+
} else {
|
|
75683
|
+
const err = "error" in outcome ? outcome.error : void 0;
|
|
75684
|
+
const kind = (0, gate_refusal_js_1.verdictKind)(outcome);
|
|
75685
|
+
body = `Tool execution failed after gate decision (verdict: ${kind}): ${(0, gate_refusal_js_1.formatGuardError)(err)}`;
|
|
75686
|
+
resultAsAnswer = true;
|
|
75687
|
+
}
|
|
75688
|
+
const result = args.attachProof === false ? body : (0, final_answer_proof_js_1.attachProofToAgentResponse)(body, outcome.proof);
|
|
75689
|
+
const out = {
|
|
75690
|
+
result,
|
|
75691
|
+
result_as_answer: resultAsAnswer,
|
|
75692
|
+
tool_name: args.tool_name,
|
|
75693
|
+
final_answer_proof: outcome.proof
|
|
75694
|
+
};
|
|
75695
|
+
return out;
|
|
75696
|
+
}
|
|
75697
|
+
}
|
|
75698
|
+
});
|
|
75699
|
+
|
|
75700
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/adapters/vercel.js
|
|
75701
|
+
var require_vercel = __commonJS({
|
|
75702
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/adapters/vercel.js"(exports2) {
|
|
75703
|
+
"use strict";
|
|
75704
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
75705
|
+
exports2.protectedToolToVercel = protectedToolToVercel;
|
|
75706
|
+
exports2.toVercelTools = toVercelTools;
|
|
75707
|
+
exports2.withCodeRiftsVercel = withCodeRiftsVercel;
|
|
75708
|
+
exports2.vercelToolAdapter = vercelToolAdapter;
|
|
75709
|
+
exports2.defaultSerializeVercelToolResult = defaultSerializeVercelToolResult;
|
|
75710
|
+
exports2.bindVercelGuardOutcome = bindVercelGuardOutcome;
|
|
75711
|
+
var with_coderifts_js_1 = require_with_coderifts();
|
|
75712
|
+
var execution_proof_js_1 = require_execution_proof();
|
|
75713
|
+
var final_answer_proof_js_1 = require_final_answer_proof();
|
|
75714
|
+
var gate_refusal_js_1 = require_gate_refusal();
|
|
75715
|
+
var EMPTY_PARAMETERS = Object.freeze({
|
|
75716
|
+
type: "object",
|
|
75717
|
+
properties: {}
|
|
75718
|
+
});
|
|
75719
|
+
function looksLikeGuardOutcome(x) {
|
|
75146
75720
|
if (!x || typeof x !== "object")
|
|
75147
75721
|
return false;
|
|
75148
75722
|
const o = x;
|
|
75149
75723
|
return typeof o.executed === "boolean" && typeof o.executionAttempted === "boolean" && o.proof != null && typeof o.proof === "object" && o.verdict != null && typeof o.verdict === "object";
|
|
75150
75724
|
}
|
|
75725
|
+
function toolCallIdFromOptions(options) {
|
|
75726
|
+
if (options && typeof options.toolCallId === "string")
|
|
75727
|
+
return options.toolCallId;
|
|
75728
|
+
return "";
|
|
75729
|
+
}
|
|
75151
75730
|
var FRESHNESS_NOT_CONFIGURED = Object.freeze({
|
|
75152
75731
|
wiring: "NOT_CONFIGURED",
|
|
75153
75732
|
write_style: false,
|
|
@@ -75159,14 +75738,7 @@ var require_execute_tool_call = __commonJS({
|
|
|
75159
75738
|
write_style: false,
|
|
75160
75739
|
mutating: false
|
|
75161
75740
|
});
|
|
75162
|
-
function
|
|
75163
|
-
return {
|
|
75164
|
-
status: "not_observed",
|
|
75165
|
-
observed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
75166
|
-
host_attestation: "absent"
|
|
75167
|
-
};
|
|
75168
|
-
}
|
|
75169
|
-
function unknownToolOutcome(toolName) {
|
|
75741
|
+
function guardedNonOutcomeRefusal(toolName) {
|
|
75170
75742
|
const verdict = {
|
|
75171
75743
|
kind: "UNAVAILABLE",
|
|
75172
75744
|
cause: "CONFIG_ERROR",
|
|
@@ -75176,7 +75748,197 @@ var require_execute_tool_call = __commonJS({
|
|
|
75176
75748
|
decisionMissing: true,
|
|
75177
75749
|
unavailableCount: 1
|
|
75178
75750
|
};
|
|
75179
|
-
const commit_observation =
|
|
75751
|
+
const commit_observation = {
|
|
75752
|
+
status: "not_observed",
|
|
75753
|
+
observed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
75754
|
+
host_attestation: "absent"
|
|
75755
|
+
};
|
|
75756
|
+
const proof = (0, execution_proof_js_1.buildExecutionProof)({
|
|
75757
|
+
preflighted: false,
|
|
75758
|
+
executionAttempted: false,
|
|
75759
|
+
executed: false,
|
|
75760
|
+
enforced: false,
|
|
75761
|
+
verdict,
|
|
75762
|
+
commitObservation: commit_observation
|
|
75763
|
+
});
|
|
75764
|
+
void toolName;
|
|
75765
|
+
return {
|
|
75766
|
+
executionAttempted: false,
|
|
75767
|
+
executed: false,
|
|
75768
|
+
enforced: false,
|
|
75769
|
+
verdict,
|
|
75770
|
+
preflighted: false,
|
|
75771
|
+
proof,
|
|
75772
|
+
freshness: FRESHNESS_NOT_CONFIGURED,
|
|
75773
|
+
conditional_write: CW_NOT_REPORTED,
|
|
75774
|
+
commit_observation
|
|
75775
|
+
};
|
|
75776
|
+
}
|
|
75777
|
+
function protectedToolToVercel(tool) {
|
|
75778
|
+
const parameters = tool.inputSchema != null && typeof tool.inputSchema === "object" && !Array.isArray(tool.inputSchema) ? tool.inputSchema : { ...EMPTY_PARAMETERS };
|
|
75779
|
+
const execute = async (args, options) => {
|
|
75780
|
+
const raw = await Promise.resolve().then(() => tool.execute(args));
|
|
75781
|
+
const bindArgs = {
|
|
75782
|
+
toolCallId: toolCallIdFromOptions(options),
|
|
75783
|
+
toolName: tool.name
|
|
75784
|
+
};
|
|
75785
|
+
if (looksLikeGuardOutcome(raw)) {
|
|
75786
|
+
return bindVercelGuardOutcome(raw, bindArgs).result;
|
|
75787
|
+
}
|
|
75788
|
+
if (tool._coderifts && tool._coderifts.guarded) {
|
|
75789
|
+
return bindVercelGuardOutcome(guardedNonOutcomeRefusal(tool.name), bindArgs).result;
|
|
75790
|
+
}
|
|
75791
|
+
return raw;
|
|
75792
|
+
};
|
|
75793
|
+
const out = {
|
|
75794
|
+
parameters,
|
|
75795
|
+
execute
|
|
75796
|
+
};
|
|
75797
|
+
if (tool.description != null && tool.description !== "") {
|
|
75798
|
+
out.description = tool.description;
|
|
75799
|
+
}
|
|
75800
|
+
return out;
|
|
75801
|
+
}
|
|
75802
|
+
function toVercelTools(protectedTools) {
|
|
75803
|
+
const out = {};
|
|
75804
|
+
for (const t of protectedTools) {
|
|
75805
|
+
out[t.name] = protectedToolToVercel(t);
|
|
75806
|
+
}
|
|
75807
|
+
return out;
|
|
75808
|
+
}
|
|
75809
|
+
function withCodeRiftsVercel(input) {
|
|
75810
|
+
const core = (0, with_coderifts_js_1.withCodeRifts)(input);
|
|
75811
|
+
return vercelToolAdapter(core);
|
|
75812
|
+
}
|
|
75813
|
+
function vercelToolAdapter(result) {
|
|
75814
|
+
const protected_tools = result.tools;
|
|
75815
|
+
const tools = toVercelTools(protected_tools);
|
|
75816
|
+
const out = {
|
|
75817
|
+
tools,
|
|
75818
|
+
protected_tools,
|
|
75819
|
+
registry_report: result.registry_report,
|
|
75820
|
+
composition_assurance: result.composition_assurance,
|
|
75821
|
+
receipt_thread: result.receipt_thread,
|
|
75822
|
+
coverage_observed: result.coverage_observed
|
|
75823
|
+
};
|
|
75824
|
+
if (result.repository !== void 0) {
|
|
75825
|
+
out.repository = result.repository;
|
|
75826
|
+
}
|
|
75827
|
+
return out;
|
|
75828
|
+
}
|
|
75829
|
+
function defaultSerializeVercelToolResult(result) {
|
|
75830
|
+
if (typeof result === "string")
|
|
75831
|
+
return result;
|
|
75832
|
+
if (typeof result === "number" || typeof result === "boolean" || typeof result === "bigint" || result === null || result === void 0) {
|
|
75833
|
+
return String(result);
|
|
75834
|
+
}
|
|
75835
|
+
try {
|
|
75836
|
+
return JSON.stringify(result);
|
|
75837
|
+
} catch {
|
|
75838
|
+
return String(result);
|
|
75839
|
+
}
|
|
75840
|
+
}
|
|
75841
|
+
function bindVercelGuardOutcome(outcome, args) {
|
|
75842
|
+
const toolCallId = args.toolCallId;
|
|
75843
|
+
const serialize = args.serialize ?? defaultSerializeVercelToolResult;
|
|
75844
|
+
let body;
|
|
75845
|
+
if (outcome.executed === true) {
|
|
75846
|
+
body = serialize(outcome.result);
|
|
75847
|
+
} else if (outcome.executionAttempted === false) {
|
|
75848
|
+
body = (0, gate_refusal_js_1.formatGateRefusalBody)(outcome);
|
|
75849
|
+
} else {
|
|
75850
|
+
const err = "error" in outcome ? outcome.error : void 0;
|
|
75851
|
+
const kind = (0, gate_refusal_js_1.verdictKind)(outcome);
|
|
75852
|
+
body = `Tool execution failed after gate decision (verdict: ${kind}): ${(0, gate_refusal_js_1.formatGuardError)(err)}`;
|
|
75853
|
+
}
|
|
75854
|
+
const result = args.attachProof === false ? body : (0, final_answer_proof_js_1.attachProofToAgentResponse)(body, outcome.proof);
|
|
75855
|
+
const part = {
|
|
75856
|
+
type: "tool-result",
|
|
75857
|
+
toolCallId,
|
|
75858
|
+
result
|
|
75859
|
+
};
|
|
75860
|
+
if (args.toolName != null && args.toolName !== "") {
|
|
75861
|
+
part.toolName = args.toolName;
|
|
75862
|
+
}
|
|
75863
|
+
return part;
|
|
75864
|
+
}
|
|
75865
|
+
}
|
|
75866
|
+
});
|
|
75867
|
+
|
|
75868
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/execute-tool-call.js
|
|
75869
|
+
var require_execute_tool_call = __commonJS({
|
|
75870
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/execute-tool-call.js"(exports2) {
|
|
75871
|
+
"use strict";
|
|
75872
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
75873
|
+
exports2.isGuardOutcome = isGuardOutcome;
|
|
75874
|
+
exports2.executeProtectedTool = executeProtectedTool;
|
|
75875
|
+
exports2.surfaceEnvelopeFields = surfaceEnvelopeFields;
|
|
75876
|
+
exports2.executeOpenAIToolCall = executeOpenAIToolCall;
|
|
75877
|
+
exports2.executeAnthropicToolCall = executeAnthropicToolCall;
|
|
75878
|
+
exports2.executeGeminiToolCall = executeGeminiToolCall;
|
|
75879
|
+
exports2.executeLangGraphToolCall = executeLangGraphToolCall;
|
|
75880
|
+
exports2.executeVercelToolCall = executeVercelToolCall;
|
|
75881
|
+
var execution_proof_js_1 = require_execution_proof();
|
|
75882
|
+
var openai_js_1 = require_openai();
|
|
75883
|
+
var anthropic_js_1 = require_anthropic();
|
|
75884
|
+
var gemini_js_1 = require_gemini();
|
|
75885
|
+
var langgraph_js_1 = require_langgraph();
|
|
75886
|
+
var vercel_js_1 = require_vercel();
|
|
75887
|
+
function resolveProtectedTools(table) {
|
|
75888
|
+
if (Array.isArray(table))
|
|
75889
|
+
return table;
|
|
75890
|
+
if (table && typeof table === "object") {
|
|
75891
|
+
const bag = table;
|
|
75892
|
+
if (Array.isArray(bag.protected_tools) && bag.protected_tools.length > 0) {
|
|
75893
|
+
return bag.protected_tools;
|
|
75894
|
+
}
|
|
75895
|
+
if (Array.isArray(bag.tools)) {
|
|
75896
|
+
const withExecute = bag.tools.filter((t) => t && typeof t === "object" && typeof t.execute === "function");
|
|
75897
|
+
if (withExecute.length > 0)
|
|
75898
|
+
return withExecute;
|
|
75899
|
+
}
|
|
75900
|
+
}
|
|
75901
|
+
return [];
|
|
75902
|
+
}
|
|
75903
|
+
function findTool(table, name) {
|
|
75904
|
+
const tools = resolveProtectedTools(table);
|
|
75905
|
+
return tools.find((t) => t && t.name === name);
|
|
75906
|
+
}
|
|
75907
|
+
function isGuardOutcome(x) {
|
|
75908
|
+
if (!x || typeof x !== "object")
|
|
75909
|
+
return false;
|
|
75910
|
+
const o = x;
|
|
75911
|
+
return typeof o.executed === "boolean" && typeof o.executionAttempted === "boolean" && o.proof != null && typeof o.proof === "object" && o.verdict != null && typeof o.verdict === "object";
|
|
75912
|
+
}
|
|
75913
|
+
var FRESHNESS_NOT_CONFIGURED = Object.freeze({
|
|
75914
|
+
wiring: "NOT_CONFIGURED",
|
|
75915
|
+
write_style: false,
|
|
75916
|
+
require_freshness: false
|
|
75917
|
+
});
|
|
75918
|
+
var CW_NOT_REPORTED = Object.freeze({
|
|
75919
|
+
conditional_write: "not_reported",
|
|
75920
|
+
require_conditional_write: false,
|
|
75921
|
+
write_style: false,
|
|
75922
|
+
mutating: false
|
|
75923
|
+
});
|
|
75924
|
+
function notObserved() {
|
|
75925
|
+
return {
|
|
75926
|
+
status: "not_observed",
|
|
75927
|
+
observed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
75928
|
+
host_attestation: "absent"
|
|
75929
|
+
};
|
|
75930
|
+
}
|
|
75931
|
+
function unknownToolOutcome(toolName) {
|
|
75932
|
+
const verdict = {
|
|
75933
|
+
kind: "UNAVAILABLE",
|
|
75934
|
+
cause: "CONFIG_ERROR",
|
|
75935
|
+
failPolicy: "closed",
|
|
75936
|
+
resolution: "CLOSED",
|
|
75937
|
+
action: "STOP",
|
|
75938
|
+
decisionMissing: true,
|
|
75939
|
+
unavailableCount: 1
|
|
75940
|
+
};
|
|
75941
|
+
const commit_observation = notObserved();
|
|
75180
75942
|
const proof = (0, execution_proof_js_1.buildExecutionProof)({
|
|
75181
75943
|
preflighted: false,
|
|
75182
75944
|
executionAttempted: false,
|
|
@@ -75382,6 +76144,26 @@ var require_execute_tool_call = __commonJS({
|
|
|
75382
76144
|
}
|
|
75383
76145
|
return bound;
|
|
75384
76146
|
}
|
|
76147
|
+
async function executeVercelToolCall(args) {
|
|
76148
|
+
const callArgs = parseMaybeJsonArgs(args.arguments);
|
|
76149
|
+
const outcome = await executeProtectedTool(args.tools, args.name, callArgs);
|
|
76150
|
+
const bound = (0, vercel_js_1.bindVercelGuardOutcome)(outcome, {
|
|
76151
|
+
toolCallId: args.toolCallId,
|
|
76152
|
+
toolName: args.name,
|
|
76153
|
+
serialize: args.serialize
|
|
76154
|
+
});
|
|
76155
|
+
if (outcome.executionAttempted === false) {
|
|
76156
|
+
const result = appendEnvelopeSurface(bound.result, outcome);
|
|
76157
|
+
const part = {
|
|
76158
|
+
type: "tool-result",
|
|
76159
|
+
toolCallId: args.toolCallId,
|
|
76160
|
+
toolName: args.name,
|
|
76161
|
+
result
|
|
76162
|
+
};
|
|
76163
|
+
return part;
|
|
76164
|
+
}
|
|
76165
|
+
return bound;
|
|
76166
|
+
}
|
|
75385
76167
|
function parseMaybeJsonArgs(args) {
|
|
75386
76168
|
if (typeof args === "string") {
|
|
75387
76169
|
const s = args.trim();
|
|
@@ -75611,9 +76393,9 @@ var require_cjs4 = __commonJS({
|
|
|
75611
76393
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
75612
76394
|
exports2.monitorAttestSigningInput = exports2.kidFromMonitoringAttestation = exports2.tryIssueMonitoringAttestation = exports2.DEFAULT_MONITORING_SINK_TIMEOUT_MS = exports2.ackBytes = exports2.verifyAckHmac = exports2.monitoringDeliveryFailClosed = exports2.formatMonitoringDeliveryLine = exports2.deliverMonitoring = exports2.hashObservedContent = exports2.observeCommit = 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.EXECUTION_TIME_FP_REASONS = exports2.EXECUTION_STATE_UNMEASURABLE_NOTE = exports2.isUnmeasurableExecutionStateReason = exports2.computeCanonicalBundleFingerprint = exports2.authorizedFingerprintFromEnvelope = exports2.checkExecutionTimeFingerprint = 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.resetPolicyWarnForTests = exports2.warnPolicyAbsentOnce = exports2.observePolicyPresence = exports2.detectPolicyPresence = exports2.policyPresenceOf = exports2.withPolicy = exports2.POLICY_ABSENT_WARN = exports2.POLICY_MARKER = exports2.CODERIFTS_POLICY = exports2.guardToolCall = void 0;
|
|
75613
76395
|
exports2.createDbVersionToken = exports2.API_ABSENT_TOKEN = exports2.API_VERSION_TOKEN_PREFIX = exports2.apiTokenRaw = exports2.writeApiIfUnchanged = exports2.createApiVersionToken = exports2.identitiesEqual = exports2.fsObjectIdentity = exports2.UnsafeCasPathError = exports2.assertSafeCasPath = exports2.FS_ABSENT_TOKEN = exports2.FS_VERSION_TOKEN_PREFIX = exports2.fsTokenContentHash = exports2.createFsPriorContentResolver = exports2.writeFileIfUnchanged = exports2.readVersionedFile = exports2.createFsVersionToken = exports2.StaleVersionTokenAbort = exports2.executeIfUnchanged = exports2.RESIDUAL_UNCONDITIONAL_WRITE = exports2.conditionalWriteResidual = exports2.tokensEqual = exports2.buildConditionalWriteBasis = exports2.buildFreshnessBasis = exports2.collectFreshnessCallContext = exports2.artifactIdsForResolve = exports2.isMutatingCall = exports2.isWriteStyleCall = exports2.freshnessAllowsEnforce = exports2.computePathSetTreeHash = exports2.contentByteIdentical = exports2.assessWriteStylePrior = exports2.assessFreshness = exports2.deriveProofBanner = exports2.attachProofToAgentResponse = exports2.renderFinalAnswerProof = exports2.EXECUTION_PROOF_SPEC = exports2.assertEnforcedReceiptInvariant = exports2.hashExecutionResult = exports2.buildExecutionProof = exports2.COVERAGE_ATTEST_ENVELOPE_TAG = exports2.COVERAGE_ATTEST_SIGNING_PREFIX = exports2.COVERAGE_ATTEST_VERSION = exports2.coverageAttestSigningInput = exports2.kidFromCoverageAttestation = exports2.tryIssueCoverageAttestation = exports2.MONITOR_ATTEST_ENVELOPE_TAG = exports2.MONITOR_ATTEST_SIGNING_PREFIX = exports2.MONITOR_ATTEST_VERSION = exports2.receiptDigestOfToken = void 0;
|
|
75614
|
-
exports2.
|
|
75615
|
-
exports2.
|
|
75616
|
-
exports2.kidFromToolsetAttestation = exports2.tryIssueToolsetAttestation = exports2.toolsetAttestSigningInput = exports2.declarationEntriesFromTools = exports2.computeToolsetDigest = exports2.TOOLSET_ATTEST_STATEMENT = exports2.TOOLSET_ATTEST_ENVELOPE_TAG = exports2.TOOLSET_ATTEST_SIGNING_PREFIX = exports2.TOOLSET_ATTEST_VERSION = exports2.surfaceEnvelopeFields = exports2.isGuardOutcome = exports2.executeLangGraphToolCall = exports2.executeGeminiToolCall = void 0;
|
|
76396
|
+
exports2.AUTO_DERIVE_READ_TIMEOUT_MS = exports2.AUTO_DERIVE_SOURCE = exports2.defaultFsReader = exports2.normalizeAutoDerive = exports2.runAutoDerive = exports2.AUTO_RECHECK_MAX_CAP = exports2.clampMaxAttempts = exports2.normalizeAutoRecheck = exports2.runAutoRecheckLoop = exports2.coverageReport = exports2.DEPLOY_REPAIRABLE_REASONS = exports2.bindDeploy = exports2.NEXT_STEP_NOTE = exports2.NEXT_AGENT_ACTIONS = exports2.readNextAgentStep = exports2.verifyDeployReceiptToken = exports2.DEPLOY_RECEIPT_VIEW_SPEC = exports2.isVerifiedDeployReceiptView = exports2.asVerifiedDeployReceiptView = exports2.deployGate = exports2.gateDecision = exports2.RegistryConstructionError = exports2.guardToolRegistry = exports2.globToRegExp = exports2.matchGlob = exports2.blobMapKey = exports2.classifyByName = exports2.resolveArtifacts = exports2.REMEDIATION_LOOP_ATTESTATION_SPEC = exports2.isCasAttestation = exports2.readPriorBlockRemediation = exports2.readRemediationTransaction = exports2.buildRemediationLoopAttestation = exports2.COMMIT_EVIDENCE_MISSING = exports2.CAS_ATTESTATION_SPEC = exports2.strictCommitObservation = exports2.extractExecutorAttestationToken = exports2.evaluateCasEvidence = exports2.isExecuteIfUnchangedOutcome = exports2.isGuardExecutionProof = exports2.buildCasAttestation = exports2.REGISTRY_ABSENT_TOKEN = exports2.REGISTRY_VERSION_TOKEN_PREFIX = exports2.registryTokenRaw = exports2.writeRegistryIfUnchanged = exports2.createRegistryVersionToken = exports2.DB_ABSENT_TOKEN = exports2.DB_VERSION_TOKEN_PREFIX = exports2.dbTokenRaw = exports2.writeDbIfUnchanged = void 0;
|
|
76397
|
+
exports2.inferFsPathFromArgs = exports2.FRESHNESS_RESOLVER_FIX = exports2.freshnessRefusalTeaching = exports2.formatGateRefusalBody = exports2.defaultSerializeLangGraphToolResult = exports2.bindLangGraphGuardOutcome = exports2.LangGraphToolsNotStructuredError = exports2.isLangGraphReactAgentTool = exports2.bindLangGraphTools = exports2.protectedToolToLangGraph = exports2.toLangGraphTools = exports2.langGraphToolAdapter = exports2.withCodeRiftsLangGraph = exports2.defaultSerializeAnthropicToolResult = exports2.bindAnthropicGuardOutcome = exports2.protectedToolToAnthropic = exports2.toAnthropicTools = exports2.anthropicToolAdapter = exports2.withCodeRiftsAnthropic = exports2.defaultSerializeOpenAIToolResult = exports2.bindOpenAIGuardOutcome = exports2.protectedToolToOpenAI = exports2.toOpenAITools = exports2.openAIToolAdapter = exports2.withCodeRiftsOpenAI = exports2.formatCoverageObservedLine = exports2.freezeCoverageObserved = exports2.createCoverageObserver = exports2.readExecutionGrantToken = exports2.isExecutionGrantEnabled = exports2.POSTURE_CLOCK_SKEW_TOLERANCE_MS = exports2.POSTURE_RECEIPT_V = exports2.verifyPostureReceipt = exports2.ATOMIC_V2_MAX_AGE_MS_CAP = exports2.CREDENTIAL_BOUNDARY_BARE_REJECTED = exports2.atomicConstructionProblems = exports2.isEnforcingAtomicV2 = exports2.PROFILE_ENFORCING_ATOMIC_V2 = exports2.isEnforcingAtomic = exports2.atomicOutcome = exports2.ATOMIC_PROFILE_UNSATISFIED = exports2.ATOMIC_INVARIANTS = exports2.createMutatorRegister = exports2._resetUnversionedProfileNoticeForTest = exports2.UNVERSIONED_PROFILE_NOTICE = exports2.PROFILE_ENFORCING_ATOMIC_V1 = exports2.PROFILE_ENFORCING_STRICT_V1 = exports2.guardedFractionAmongRoutes = exports2.foldTableSettledCalls = exports2.withCodeRifts = void 0;
|
|
76398
|
+
exports2.kidFromToolsetAttestation = exports2.tryIssueToolsetAttestation = exports2.toolsetAttestSigningInput = exports2.declarationEntriesFromTools = exports2.computeToolsetDigest = exports2.TOOLSET_ATTEST_STATEMENT = exports2.TOOLSET_ATTEST_ENVELOPE_TAG = exports2.TOOLSET_ATTEST_SIGNING_PREFIX = exports2.TOOLSET_ATTEST_VERSION = exports2.surfaceEnvelopeFields = exports2.isGuardOutcome = exports2.executeVercelToolCall = exports2.executeLangGraphToolCall = exports2.executeGeminiToolCall = exports2.executeAnthropicToolCall = exports2.executeOpenAIToolCall = exports2.executeProtectedTool = exports2.defaultSerializeVercelToolResult = exports2.bindVercelGuardOutcome = exports2.protectedToolToVercel = exports2.toVercelTools = exports2.vercelToolAdapter = exports2.withCodeRiftsVercel = exports2.defaultSerializeCrewAIToolResult = exports2.bindCrewAIToolOutcome = exports2.LANGCHAIN_ARTIFACT_SPEC = exports2.defaultSerializeLangChainToolResult = exports2.bindLangChainToolOutcome = exports2.defaultSerializeGeminiToolResult = exports2.bindGeminiGuardOutcome = exports2.protectedToolToFunctionDeclaration = exports2.toGeminiTools = exports2.geminiToolAdapter = exports2.withCodeRiftsGemini = exports2.measureFsAuthorizationToken = exports2.measureFsAuthorization = exports2.wrapWriteWithFsCas = exports2.inferFullFileWriteContent = void 0;
|
|
75617
76399
|
var guard_js_1 = require_guard();
|
|
75618
76400
|
Object.defineProperty(exports2, "guardToolCall", { enumerable: true, get: function() {
|
|
75619
76401
|
return guard_js_1.guardToolCall;
|
|
@@ -76048,6 +76830,16 @@ var require_cjs4 = __commonJS({
|
|
|
76048
76830
|
Object.defineProperty(exports2, "verifyDeployReceiptToken", { enumerable: true, get: function() {
|
|
76049
76831
|
return deploy_receipt_token_js_1.verifyDeployReceiptToken;
|
|
76050
76832
|
} });
|
|
76833
|
+
var next_agent_step_js_1 = require_next_agent_step();
|
|
76834
|
+
Object.defineProperty(exports2, "readNextAgentStep", { enumerable: true, get: function() {
|
|
76835
|
+
return next_agent_step_js_1.readNextAgentStep;
|
|
76836
|
+
} });
|
|
76837
|
+
Object.defineProperty(exports2, "NEXT_AGENT_ACTIONS", { enumerable: true, get: function() {
|
|
76838
|
+
return next_agent_step_js_1.NEXT_AGENT_ACTIONS;
|
|
76839
|
+
} });
|
|
76840
|
+
Object.defineProperty(exports2, "NEXT_STEP_NOTE", { enumerable: true, get: function() {
|
|
76841
|
+
return next_agent_step_js_1.NEXT_STEP_NOTE;
|
|
76842
|
+
} });
|
|
76051
76843
|
var deploy_bind_js_1 = require_deploy_bind();
|
|
76052
76844
|
Object.defineProperty(exports2, "bindDeploy", { enumerable: true, get: function() {
|
|
76053
76845
|
return deploy_bind_js_1.bindDeploy;
|
|
@@ -76104,6 +76896,12 @@ var require_cjs4 = __commonJS({
|
|
|
76104
76896
|
Object.defineProperty(exports2, "PROFILE_ENFORCING_ATOMIC_V1", { enumerable: true, get: function() {
|
|
76105
76897
|
return with_coderifts_js_1.PROFILE_ENFORCING_ATOMIC_V1;
|
|
76106
76898
|
} });
|
|
76899
|
+
Object.defineProperty(exports2, "UNVERSIONED_PROFILE_NOTICE", { enumerable: true, get: function() {
|
|
76900
|
+
return with_coderifts_js_1.UNVERSIONED_PROFILE_NOTICE;
|
|
76901
|
+
} });
|
|
76902
|
+
Object.defineProperty(exports2, "_resetUnversionedProfileNoticeForTest", { enumerable: true, get: function() {
|
|
76903
|
+
return with_coderifts_js_1._resetUnversionedProfileNoticeForTest;
|
|
76904
|
+
} });
|
|
76107
76905
|
var atomic_profile_js_1 = require_atomic_profile();
|
|
76108
76906
|
Object.defineProperty(exports2, "createMutatorRegister", { enumerable: true, get: function() {
|
|
76109
76907
|
return atomic_profile_js_1.createMutatorRegister;
|
|
@@ -76120,6 +76918,31 @@ var require_cjs4 = __commonJS({
|
|
|
76120
76918
|
Object.defineProperty(exports2, "isEnforcingAtomic", { enumerable: true, get: function() {
|
|
76121
76919
|
return atomic_profile_js_1.isEnforcingAtomic;
|
|
76122
76920
|
} });
|
|
76921
|
+
Object.defineProperty(exports2, "PROFILE_ENFORCING_ATOMIC_V2", { enumerable: true, get: function() {
|
|
76922
|
+
return atomic_profile_js_1.PROFILE_ENFORCING_ATOMIC_V2;
|
|
76923
|
+
} });
|
|
76924
|
+
Object.defineProperty(exports2, "isEnforcingAtomicV2", { enumerable: true, get: function() {
|
|
76925
|
+
return atomic_profile_js_1.isEnforcingAtomicV2;
|
|
76926
|
+
} });
|
|
76927
|
+
Object.defineProperty(exports2, "atomicConstructionProblems", { enumerable: true, get: function() {
|
|
76928
|
+
return atomic_profile_js_1.atomicConstructionProblems;
|
|
76929
|
+
} });
|
|
76930
|
+
Object.defineProperty(exports2, "CREDENTIAL_BOUNDARY_BARE_REJECTED", { enumerable: true, get: function() {
|
|
76931
|
+
return atomic_profile_js_1.CREDENTIAL_BOUNDARY_BARE_REJECTED;
|
|
76932
|
+
} });
|
|
76933
|
+
Object.defineProperty(exports2, "ATOMIC_V2_MAX_AGE_MS_CAP", { enumerable: true, get: function() {
|
|
76934
|
+
return atomic_profile_js_1.ATOMIC_V2_MAX_AGE_MS_CAP;
|
|
76935
|
+
} });
|
|
76936
|
+
var posture_receipt_js_1 = require_posture_receipt();
|
|
76937
|
+
Object.defineProperty(exports2, "verifyPostureReceipt", { enumerable: true, get: function() {
|
|
76938
|
+
return posture_receipt_js_1.verifyPostureReceipt;
|
|
76939
|
+
} });
|
|
76940
|
+
Object.defineProperty(exports2, "POSTURE_RECEIPT_V", { enumerable: true, get: function() {
|
|
76941
|
+
return posture_receipt_js_1.POSTURE_RECEIPT_V;
|
|
76942
|
+
} });
|
|
76943
|
+
Object.defineProperty(exports2, "POSTURE_CLOCK_SKEW_TOLERANCE_MS", { enumerable: true, get: function() {
|
|
76944
|
+
return posture_receipt_js_1.POSTURE_CLOCK_SKEW_TOLERANCE_MS;
|
|
76945
|
+
} });
|
|
76123
76946
|
var execution_grant_js_1 = require_execution_grant2();
|
|
76124
76947
|
Object.defineProperty(exports2, "isExecutionGrantEnabled", { enumerable: true, get: function() {
|
|
76125
76948
|
return execution_grant_js_1.isExecutionGrantEnabled;
|
|
@@ -76248,6 +77071,42 @@ var require_cjs4 = __commonJS({
|
|
|
76248
77071
|
Object.defineProperty(exports2, "defaultSerializeGeminiToolResult", { enumerable: true, get: function() {
|
|
76249
77072
|
return gemini_js_1.defaultSerializeGeminiToolResult;
|
|
76250
77073
|
} });
|
|
77074
|
+
var langchain_js_1 = require_langchain();
|
|
77075
|
+
Object.defineProperty(exports2, "bindLangChainToolOutcome", { enumerable: true, get: function() {
|
|
77076
|
+
return langchain_js_1.bindLangChainToolOutcome;
|
|
77077
|
+
} });
|
|
77078
|
+
Object.defineProperty(exports2, "defaultSerializeLangChainToolResult", { enumerable: true, get: function() {
|
|
77079
|
+
return langchain_js_1.defaultSerializeLangChainToolResult;
|
|
77080
|
+
} });
|
|
77081
|
+
Object.defineProperty(exports2, "LANGCHAIN_ARTIFACT_SPEC", { enumerable: true, get: function() {
|
|
77082
|
+
return langchain_js_1.LANGCHAIN_ARTIFACT_SPEC;
|
|
77083
|
+
} });
|
|
77084
|
+
var crewai_js_1 = require_crewai();
|
|
77085
|
+
Object.defineProperty(exports2, "bindCrewAIToolOutcome", { enumerable: true, get: function() {
|
|
77086
|
+
return crewai_js_1.bindCrewAIToolOutcome;
|
|
77087
|
+
} });
|
|
77088
|
+
Object.defineProperty(exports2, "defaultSerializeCrewAIToolResult", { enumerable: true, get: function() {
|
|
77089
|
+
return crewai_js_1.defaultSerializeCrewAIToolResult;
|
|
77090
|
+
} });
|
|
77091
|
+
var vercel_js_1 = require_vercel();
|
|
77092
|
+
Object.defineProperty(exports2, "withCodeRiftsVercel", { enumerable: true, get: function() {
|
|
77093
|
+
return vercel_js_1.withCodeRiftsVercel;
|
|
77094
|
+
} });
|
|
77095
|
+
Object.defineProperty(exports2, "vercelToolAdapter", { enumerable: true, get: function() {
|
|
77096
|
+
return vercel_js_1.vercelToolAdapter;
|
|
77097
|
+
} });
|
|
77098
|
+
Object.defineProperty(exports2, "toVercelTools", { enumerable: true, get: function() {
|
|
77099
|
+
return vercel_js_1.toVercelTools;
|
|
77100
|
+
} });
|
|
77101
|
+
Object.defineProperty(exports2, "protectedToolToVercel", { enumerable: true, get: function() {
|
|
77102
|
+
return vercel_js_1.protectedToolToVercel;
|
|
77103
|
+
} });
|
|
77104
|
+
Object.defineProperty(exports2, "bindVercelGuardOutcome", { enumerable: true, get: function() {
|
|
77105
|
+
return vercel_js_1.bindVercelGuardOutcome;
|
|
77106
|
+
} });
|
|
77107
|
+
Object.defineProperty(exports2, "defaultSerializeVercelToolResult", { enumerable: true, get: function() {
|
|
77108
|
+
return vercel_js_1.defaultSerializeVercelToolResult;
|
|
77109
|
+
} });
|
|
76251
77110
|
var execute_tool_call_js_1 = require_execute_tool_call();
|
|
76252
77111
|
Object.defineProperty(exports2, "executeProtectedTool", { enumerable: true, get: function() {
|
|
76253
77112
|
return execute_tool_call_js_1.executeProtectedTool;
|
|
@@ -76264,6 +77123,9 @@ var require_cjs4 = __commonJS({
|
|
|
76264
77123
|
Object.defineProperty(exports2, "executeLangGraphToolCall", { enumerable: true, get: function() {
|
|
76265
77124
|
return execute_tool_call_js_1.executeLangGraphToolCall;
|
|
76266
77125
|
} });
|
|
77126
|
+
Object.defineProperty(exports2, "executeVercelToolCall", { enumerable: true, get: function() {
|
|
77127
|
+
return execute_tool_call_js_1.executeVercelToolCall;
|
|
77128
|
+
} });
|
|
76267
77129
|
Object.defineProperty(exports2, "isGuardOutcome", { enumerable: true, get: function() {
|
|
76268
77130
|
return execute_tool_call_js_1.isGuardOutcome;
|
|
76269
77131
|
} });
|
|
@@ -76311,6 +77173,24 @@ var require_claude_hook = __commonJS({
|
|
|
76311
77173
|
var { getApiKey } = require_config();
|
|
76312
77174
|
var { cloudAuthorizePreflight } = require_cloud();
|
|
76313
77175
|
var DEFAULT_SPEC_PATH = "api/openapi.yaml";
|
|
77176
|
+
var DEFAULT_SPEC_GLOBS = Object.freeze([
|
|
77177
|
+
"**/*openapi*.yaml",
|
|
77178
|
+
"**/*openapi*.yml",
|
|
77179
|
+
"**/*openapi*.json",
|
|
77180
|
+
"**/*swagger*.yaml",
|
|
77181
|
+
"**/*swagger*.yml",
|
|
77182
|
+
"**/*swagger*.json",
|
|
77183
|
+
"**/*asyncapi*.yaml",
|
|
77184
|
+
"**/*asyncapi*.yml",
|
|
77185
|
+
"**/*asyncapi*.json",
|
|
77186
|
+
"**/*.graphql",
|
|
77187
|
+
"**/*.gql",
|
|
77188
|
+
"**/*.proto",
|
|
77189
|
+
"**/*mcp*.json",
|
|
77190
|
+
"**/*mcp*.yaml",
|
|
77191
|
+
"**/*mcp*.yml",
|
|
77192
|
+
"**/*tool-schema*.json"
|
|
77193
|
+
]);
|
|
76314
77194
|
var CLOSED_ACTIONS = /* @__PURE__ */ new Set([
|
|
76315
77195
|
"CONTINUE",
|
|
76316
77196
|
"CONTINUE_WITH_MONITORING",
|
|
@@ -76320,8 +77200,9 @@ var require_claude_hook = __commonJS({
|
|
|
76320
77200
|
var USAGE = [
|
|
76321
77201
|
"Usage: coderifts claude-hook",
|
|
76322
77202
|
"",
|
|
76323
|
-
"Claude Code PreToolUse hook: gates Write|Edit|MultiEdit when they touch
|
|
76324
|
-
"
|
|
77203
|
+
"Claude Code PreToolUse hook: gates Write|Edit|MultiEdit when they touch a",
|
|
77204
|
+
"governed contract path (default family + git config coderifts.specPath).",
|
|
77205
|
+
"Reads JSON context from STDIN.",
|
|
76325
77206
|
"",
|
|
76326
77207
|
"Exit map (Claude Code semantics \u2014 get this exactly right):",
|
|
76327
77208
|
" 2 BLOCK \u2014 tool call cancelled (BLOCK/STOP, REQUEST_APPROVAL, unrecognised action,",
|
|
@@ -76336,7 +77217,7 @@ var require_claude_hook = __commonJS({
|
|
|
76336
77217
|
"Parse-gap DEFAULT (exit 2): unparseable stdin / missing file_path \u2014 refusing (fail-closed);",
|
|
76337
77218
|
" set CODERIFTS_ADVISORY=1 to soften. JSONL hook_blocked cause stdin_unparseable|missing_file_path.",
|
|
76338
77219
|
"",
|
|
76339
|
-
"Still exit 0 (nothing to govern):
|
|
77220
|
+
"Still exit 0 (nothing to govern): not-governed path (one stderr line), identical content, non-governed tool.",
|
|
76340
77221
|
"",
|
|
76341
77222
|
"CONTINUE_WITH_MONITORING: allow only if the host asserts a sink",
|
|
76342
77223
|
" (CODERIFTS_MONITORING_SINK_WIRED=1|true or git config coderifts.monitoringSinkWired).",
|
|
@@ -76344,8 +77225,11 @@ var require_claude_hook = __commonJS({
|
|
|
76344
77225
|
"",
|
|
76345
77226
|
"CODERIFTS_STRICT=1|true: same fail-closed as default; cannot be weakened by ADVISORY.",
|
|
76346
77227
|
"",
|
|
76347
|
-
"
|
|
76348
|
-
"
|
|
77228
|
+
"Governed paths (additive; configuring one path never drops the defaults):",
|
|
77229
|
+
" default family: OpenAPI/Swagger, GraphQL, *.proto, AsyncAPI, MCP manifest, tool-schema.json",
|
|
77230
|
+
" git config --add coderifts.specPath <path-or-glob> # extra includes",
|
|
77231
|
+
" git config --add coderifts.specPathExclude <path-or-glob> # opt out one path",
|
|
77232
|
+
" Not-governed path: exit 0 and one stderr line `coderifts claude-hook: not governed: <path>`.",
|
|
76349
77233
|
"",
|
|
76350
77234
|
"Baseline at PreToolUse: before = current file on disk (pre-edit state \u2014 the tool has",
|
|
76351
77235
|
"not written yet). after = proposed content from tool_input (Write: content; Edit/MultiEdit:",
|
|
@@ -76473,10 +77357,41 @@ var require_claude_hook = __commonJS({
|
|
|
76473
77357
|
return readGitConfig("coderifts.apiKey", deps);
|
|
76474
77358
|
}
|
|
76475
77359
|
function resolveSpecPath(deps = {}) {
|
|
77360
|
+
const extras = readGitConfigAll("coderifts.specPath", deps);
|
|
77361
|
+
if (extras.length) return extras[0];
|
|
76476
77362
|
const fromGit = readGitConfig("coderifts.specPath", deps);
|
|
76477
|
-
if (fromGit) return fromGit;
|
|
77363
|
+
if (fromGit) return splitConfigValues(fromGit)[0] || DEFAULT_SPEC_PATH;
|
|
76478
77364
|
return DEFAULT_SPEC_PATH;
|
|
76479
77365
|
}
|
|
77366
|
+
function splitConfigValues(raw) {
|
|
77367
|
+
return String(raw || "").split(/[\n,]/).map((s) => s.trim()).filter(Boolean);
|
|
77368
|
+
}
|
|
77369
|
+
function readGitConfigAll(key, deps = {}) {
|
|
77370
|
+
if (typeof deps.readGitConfigAll === "function") {
|
|
77371
|
+
const v = deps.readGitConfigAll(key);
|
|
77372
|
+
if (Array.isArray(v)) return v.flatMap(splitConfigValues);
|
|
77373
|
+
return splitConfigValues(v);
|
|
77374
|
+
}
|
|
77375
|
+
const run = deps.execSync || execSync;
|
|
77376
|
+
const cwd = deps.cwd || process.cwd();
|
|
77377
|
+
try {
|
|
77378
|
+
const v = run(`git config --get-all ${key}`, {
|
|
77379
|
+
encoding: "utf8",
|
|
77380
|
+
cwd,
|
|
77381
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
77382
|
+
});
|
|
77383
|
+
return splitConfigValues(v);
|
|
77384
|
+
} catch {
|
|
77385
|
+
const one = readGitConfig(key, deps);
|
|
77386
|
+
return one ? splitConfigValues(one) : [];
|
|
77387
|
+
}
|
|
77388
|
+
}
|
|
77389
|
+
function resolveSpecIncludes(deps = {}) {
|
|
77390
|
+
return readGitConfigAll("coderifts.specPath", deps);
|
|
77391
|
+
}
|
|
77392
|
+
function resolveSpecExcludes(deps = {}) {
|
|
77393
|
+
return readGitConfigAll("coderifts.specPathExclude", deps);
|
|
77394
|
+
}
|
|
76480
77395
|
var GOVERNED_TOOLS = /* @__PURE__ */ new Set(["write", "edit", "multiedit", "multi_edit"]);
|
|
76481
77396
|
function isGovernedTool(name) {
|
|
76482
77397
|
return GOVERNED_TOOLS.has(String(name || "").toLowerCase());
|
|
@@ -76551,6 +77466,75 @@ var require_claude_hook = __commonJS({
|
|
|
76551
77466
|
}
|
|
76552
77467
|
return false;
|
|
76553
77468
|
}
|
|
77469
|
+
function globToRegExp(pattern) {
|
|
77470
|
+
const src = String(pattern).replace(/\\/g, "/");
|
|
77471
|
+
let out = "^";
|
|
77472
|
+
for (let i = 0; i < src.length; ) {
|
|
77473
|
+
if (src[i] === "*" && src[i + 1] === "*") {
|
|
77474
|
+
if (src[i + 2] === "/") {
|
|
77475
|
+
out += "(?:.*/)?";
|
|
77476
|
+
i += 3;
|
|
77477
|
+
} else {
|
|
77478
|
+
out += ".*";
|
|
77479
|
+
i += 2;
|
|
77480
|
+
}
|
|
77481
|
+
} else if (src[i] === "*") {
|
|
77482
|
+
out += "[^/]*";
|
|
77483
|
+
i += 1;
|
|
77484
|
+
} else if (src[i] === "?") {
|
|
77485
|
+
out += "[^/]";
|
|
77486
|
+
i += 1;
|
|
77487
|
+
} else {
|
|
77488
|
+
out += src[i].replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
77489
|
+
i += 1;
|
|
77490
|
+
}
|
|
77491
|
+
}
|
|
77492
|
+
out += "$";
|
|
77493
|
+
return new RegExp(out, "i");
|
|
77494
|
+
}
|
|
77495
|
+
function matchGlob(pattern, value) {
|
|
77496
|
+
if (!pattern || value == null) return false;
|
|
77497
|
+
return globToRegExp(pattern).test(String(value).replace(/\\/g, "/"));
|
|
77498
|
+
}
|
|
77499
|
+
function normalizeToolPath(filePath, cwd) {
|
|
77500
|
+
let p = String(filePath || "").replace(/\\/g, "/");
|
|
77501
|
+
while (p.startsWith("./")) p = p.slice(2);
|
|
77502
|
+
const root = String(cwd || "").replace(/\\/g, "/").replace(/\/$/, "");
|
|
77503
|
+
if (root && (p === root || p.startsWith(`${root}/`))) {
|
|
77504
|
+
p = p.slice(root.length).replace(/^\//, "");
|
|
77505
|
+
}
|
|
77506
|
+
return p;
|
|
77507
|
+
}
|
|
77508
|
+
function isDetectorsExcludedDir(rel) {
|
|
77509
|
+
const s = `/${String(rel).replace(/\\/g, "/").toLowerCase()}/`;
|
|
77510
|
+
return s.includes("/node_modules/") || s.includes("/vendor/");
|
|
77511
|
+
}
|
|
77512
|
+
function patternLooksLikeGlob(pattern) {
|
|
77513
|
+
return /[*?]/.test(String(pattern || ""));
|
|
77514
|
+
}
|
|
77515
|
+
function matchesPattern(filePath, rel, pattern) {
|
|
77516
|
+
if (!pattern) return false;
|
|
77517
|
+
if (patternLooksLikeGlob(pattern)) {
|
|
77518
|
+
return matchGlob(pattern, rel) || matchGlob(pattern, filePath);
|
|
77519
|
+
}
|
|
77520
|
+
return isSpecPath(filePath, pattern) || isSpecPath(rel, pattern);
|
|
77521
|
+
}
|
|
77522
|
+
function matchesAnyPattern(filePath, rel, patterns) {
|
|
77523
|
+
for (const p of patterns || []) {
|
|
77524
|
+
if (matchesPattern(filePath, rel, p)) return true;
|
|
77525
|
+
}
|
|
77526
|
+
return false;
|
|
77527
|
+
}
|
|
77528
|
+
function isGovernedPath(filePath, deps = {}) {
|
|
77529
|
+
if (!filePath) return false;
|
|
77530
|
+
const rel = normalizeToolPath(filePath, deps.cwd);
|
|
77531
|
+
const extras = resolveSpecIncludes(deps);
|
|
77532
|
+
const excludes = resolveSpecExcludes(deps);
|
|
77533
|
+
if (matchesAnyPattern(filePath, rel, excludes)) return false;
|
|
77534
|
+
if (matchesAnyPattern(filePath, rel, extras)) return true;
|
|
77535
|
+
if (isDetectorsExcludedDir(rel)) return false;
|
|
77536
|
+
return DEFAULT_SPEC_GLOBS.some((g) => matchGlob(g, rel) || matchGlob(g, String(filePath).replace(/\\/g, "/")));
|
|
77537
|
+
}
|
|
76554
77538
|
function deriveAfterContent(toolName, toolInput, diskBefore) {
|
|
76555
77539
|
const name = String(toolName || "").toLowerCase();
|
|
76556
77540
|
if (name === "write") {
|
|
@@ -76779,8 +77763,9 @@ var require_claude_hook = __commonJS({
|
|
|
76779
77763
|
return emitTerminal({ exitCode: 2, reason: "missing_file_path" });
|
|
76780
77764
|
}
|
|
76781
77765
|
filePathKnown = filePath;
|
|
76782
|
-
|
|
76783
|
-
|
|
77766
|
+
if (!isGovernedPath(filePath, { ...deps, cwd })) {
|
|
77767
|
+
const rel = normalizeToolPath(filePath, cwd);
|
|
77768
|
+
errLog(`coderifts claude-hook: not governed: ${rel || filePath}`);
|
|
76784
77769
|
logEv({ type: "detection_skip", signals: ["not_spec_path"], tool, path: filePath });
|
|
76785
77770
|
return emitTerminal({ exitCode: 0, reason: "not_spec_path" });
|
|
76786
77771
|
}
|
|
@@ -76961,12 +77946,18 @@ var require_claude_hook = __commonJS({
|
|
|
76961
77946
|
isGovernedTool,
|
|
76962
77947
|
coerceToolInput,
|
|
76963
77948
|
isSpecPath,
|
|
77949
|
+
isGovernedPath,
|
|
77950
|
+
matchGlob,
|
|
77951
|
+
normalizeToolPath,
|
|
76964
77952
|
deriveAfterContent,
|
|
76965
77953
|
mapDecisionSeverity,
|
|
76966
77954
|
renderDecisionWhy,
|
|
76967
77955
|
resolveApiKey,
|
|
76968
77956
|
resolveSpecPath,
|
|
77957
|
+
resolveSpecIncludes,
|
|
77958
|
+
resolveSpecExcludes,
|
|
76969
77959
|
readGitConfig,
|
|
77960
|
+
readGitConfigAll,
|
|
76970
77961
|
isEnvFlag,
|
|
76971
77962
|
isStrictMode,
|
|
76972
77963
|
isAdvisoryMode,
|
|
@@ -76974,6 +77965,7 @@ var require_claude_hook = __commonJS({
|
|
|
76974
77965
|
failClosedOrAdvisory,
|
|
76975
77966
|
softOrStrictBlock,
|
|
76976
77967
|
DEFAULT_SPEC_PATH,
|
|
77968
|
+
DEFAULT_SPEC_GLOBS,
|
|
76977
77969
|
CLOSED_ACTIONS,
|
|
76978
77970
|
USAGE,
|
|
76979
77971
|
appendGuardEventLog,
|
|
@@ -158775,7 +159767,7 @@ var require_rateLimit = __commonJS({
|
|
|
158775
159767
|
var ipDailyStore = /* @__PURE__ */ new Map();
|
|
158776
159768
|
var apiKeyMinuteStore = /* @__PURE__ */ new Map();
|
|
158777
159769
|
var ipAgentMinuteStore = /* @__PURE__ */ new Map();
|
|
158778
|
-
var AGENT_PUBLIC_ENDPOINTS = ["/api/v1/demo", "/api/v1/public/preflight", "/api/v1/public/actionguard-check", "/api/v1/public/migraguard-check", "/api/v1/badge/agent-readiness"];
|
|
159770
|
+
var AGENT_PUBLIC_ENDPOINTS = ["/api/v1/demo", "/api/v1/public/preflight", "/api/v1/public/actionguard-check", "/api/v1/public/migraguard-check", "/api/v1/badge/agent-readiness", "/snippets"];
|
|
158779
159771
|
var AGENT_IP_MINUTE_LIMIT = 60;
|
|
158780
159772
|
var ANONYMOUS_DAILY_LIMIT = 50;
|
|
158781
159773
|
var API_KEY_MINUTE_LIMIT = 100;
|
|
@@ -179997,6 +180989,32 @@ var require_comment_renderer = __commonJS({
|
|
|
179997
180989
|
lines.push("");
|
|
179998
180990
|
return lines.join("\n");
|
|
179999
180991
|
}
|
|
180992
|
+
var BREAKING_HIGHLIGHTS_TOP_N = 5;
|
|
180993
|
+
function renderBreakingHighlights(results, topN = BREAKING_HIGHLIGHTS_TOP_N) {
|
|
180994
|
+
if (!Array.isArray(results) || results.length === 0) return "";
|
|
180995
|
+
const rows = [];
|
|
180996
|
+
for (const r of results) {
|
|
180997
|
+
const file = r && typeof r.schemaPath === "string" ? r.schemaPath : "";
|
|
180998
|
+
for (const d of r && Array.isArray(r.breaking) ? r.breaking : []) {
|
|
180999
|
+
const raw = extractRawLocation(d);
|
|
181000
|
+
const pointer = raw && raw !== "N/A" ? raw : "";
|
|
181001
|
+
if (!file && !pointer) continue;
|
|
181002
|
+
rows.push({ file, pointer, code: d && d.code ? String(d.code) : "" });
|
|
181003
|
+
}
|
|
181004
|
+
}
|
|
181005
|
+
if (rows.length === 0) return "";
|
|
181006
|
+
const shown = rows.slice(0, topN);
|
|
181007
|
+
const lines = ["## \u{1F3AF} Breaking elements\n"];
|
|
181008
|
+
for (const row of shown) {
|
|
181009
|
+
const where = row.file && row.pointer ? `\`${escapeMd(row.file)}\` \xB7 \`${escapeMd(row.pointer)}\`` : `\`${escapeMd(row.file || row.pointer)}\``;
|
|
181010
|
+
lines.push(`- ${where}${row.code ? ` \u2014 \`${escapeMd(row.code)}\`` : ""}`);
|
|
181011
|
+
}
|
|
181012
|
+
if (rows.length > shown.length) {
|
|
181013
|
+
lines.push(`- \u2026and ${rows.length - shown.length} more \u2014 see **Raw diff details** below.`);
|
|
181014
|
+
}
|
|
181015
|
+
lines.push("");
|
|
181016
|
+
return lines.join("\n");
|
|
181017
|
+
}
|
|
180000
181018
|
function renderAgentImpactHeadline(options) {
|
|
180001
181019
|
const n = (options.omegaAgentPatterns || []).length;
|
|
180002
181020
|
if (n === 0) return "";
|
|
@@ -180246,6 +181264,10 @@ var require_comment_renderer = __commonJS({
|
|
|
180246
181264
|
const changeList = renderCanonicalChangeList(options.detectedPatterns || []);
|
|
180247
181265
|
if (changeList) lines.push(changeList);
|
|
180248
181266
|
}
|
|
181267
|
+
{
|
|
181268
|
+
const highlights = renderBreakingHighlights(results);
|
|
181269
|
+
if (highlights) lines.push(highlights);
|
|
181270
|
+
}
|
|
180249
181271
|
{
|
|
180250
181272
|
const agentLine = renderAgentImpactHeadline(options);
|
|
180251
181273
|
if (agentLine) lines.push(agentLine);
|
|
@@ -180728,6 +181750,8 @@ ${body}` : poison;
|
|
|
180728
181750
|
renderBlockReason,
|
|
180729
181751
|
renderUnblockActions,
|
|
180730
181752
|
renderCanonicalChangeList,
|
|
181753
|
+
renderBreakingHighlights,
|
|
181754
|
+
BREAKING_HIGHLIGHTS_TOP_N,
|
|
180731
181755
|
renderAgentImpactHeadline,
|
|
180732
181756
|
renderEconomicHeadline,
|
|
180733
181757
|
renderPoisonGateSection,
|
|
@@ -201561,7 +202585,120 @@ var require_asyncapi_diff = __commonJS({
|
|
|
201561
202585
|
channels[channelName] = { operations };
|
|
201562
202586
|
}
|
|
201563
202587
|
}
|
|
201564
|
-
return { channels };
|
|
202588
|
+
return { channels, root: parsed };
|
|
202589
|
+
}
|
|
202590
|
+
function stillHasRef(node) {
|
|
202591
|
+
return !!(node && typeof node === "object" && typeof node.$ref === "string" && !node.properties);
|
|
202592
|
+
}
|
|
202593
|
+
function comparePayload(basePayload, headPayload, pathPrefix, messageId, baseRoot, headRoot, addBreakingChange, addNonBreakingChange) {
|
|
202594
|
+
const baseResolved = resolveLocalRef(baseRoot, basePayload, []);
|
|
202595
|
+
const headResolved = resolveLocalRef(headRoot, headPayload, []);
|
|
202596
|
+
if (stillHasRef(baseResolved) || stillHasRef(headResolved)) {
|
|
202597
|
+
const ref = stillHasRef(baseResolved) && baseResolved.$ref || stillHasRef(headResolved) && headResolved.$ref || "";
|
|
202598
|
+
addNonBreakingChange(
|
|
202599
|
+
"PAYLOAD_REF_UNCOMPARED",
|
|
202600
|
+
pathPrefix,
|
|
202601
|
+
`Payload at '${pathPrefix}' uses unresolved $ref '${ref}' and was not compared.`
|
|
202602
|
+
);
|
|
202603
|
+
return;
|
|
202604
|
+
}
|
|
202605
|
+
if (!baseResolved || !headResolved || typeof baseResolved !== "object" || typeof headResolved !== "object") {
|
|
202606
|
+
return;
|
|
202607
|
+
}
|
|
202608
|
+
const baseProps = baseResolved.properties || {};
|
|
202609
|
+
const headProps = headResolved.properties || {};
|
|
202610
|
+
const baseReq = new Set(Array.isArray(baseResolved.required) ? baseResolved.required : []);
|
|
202611
|
+
const headReq = new Set(Array.isArray(headResolved.required) ? headResolved.required : []);
|
|
202612
|
+
for (const fieldName of headReq) {
|
|
202613
|
+
if (baseReq.has(fieldName)) continue;
|
|
202614
|
+
if (baseProps[fieldName]) {
|
|
202615
|
+
addBreakingChange(
|
|
202616
|
+
"PAYLOAD_FIELD_NOW_REQUIRED",
|
|
202617
|
+
`${pathPrefix}.${fieldName}`,
|
|
202618
|
+
`Payload field '${fieldName}' in message '${messageId}' changed from optional to required.`
|
|
202619
|
+
);
|
|
202620
|
+
} else {
|
|
202621
|
+
addBreakingChange(
|
|
202622
|
+
"REQUIRED_PAYLOAD_FIELD_ADDED",
|
|
202623
|
+
`${pathPrefix}.${fieldName}`,
|
|
202624
|
+
`Required payload field '${fieldName}' was added to message '${messageId}'.`
|
|
202625
|
+
);
|
|
202626
|
+
}
|
|
202627
|
+
}
|
|
202628
|
+
for (const fieldName of baseReq) {
|
|
202629
|
+
if (!headReq.has(fieldName) && headProps[fieldName]) {
|
|
202630
|
+
addNonBreakingChange(
|
|
202631
|
+
"PAYLOAD_FIELD_NOW_OPTIONAL",
|
|
202632
|
+
`${pathPrefix}.${fieldName}`,
|
|
202633
|
+
`Payload field '${fieldName}' in message '${messageId}' changed from required to optional.`
|
|
202634
|
+
);
|
|
202635
|
+
}
|
|
202636
|
+
}
|
|
202637
|
+
for (const fieldName in baseProps) {
|
|
202638
|
+
const baseField = resolveLocalRef(baseRoot, baseProps[fieldName], []);
|
|
202639
|
+
const headFieldRaw = headProps[fieldName];
|
|
202640
|
+
if (!headFieldRaw) {
|
|
202641
|
+
addBreakingChange(
|
|
202642
|
+
"PAYLOAD_FIELD_REMOVED",
|
|
202643
|
+
`${pathPrefix}.${fieldName}`,
|
|
202644
|
+
`Payload field '${fieldName}' was removed from message '${messageId}'.`
|
|
202645
|
+
);
|
|
202646
|
+
continue;
|
|
202647
|
+
}
|
|
202648
|
+
const headField = resolveLocalRef(headRoot, headFieldRaw, []);
|
|
202649
|
+
if (stillHasRef(baseField) || stillHasRef(headField)) {
|
|
202650
|
+
const ref = stillHasRef(baseField) && baseField.$ref || stillHasRef(headField) && headField.$ref || "";
|
|
202651
|
+
addNonBreakingChange(
|
|
202652
|
+
"PAYLOAD_REF_UNCOMPARED",
|
|
202653
|
+
`${pathPrefix}.${fieldName}`,
|
|
202654
|
+
`Payload field '${fieldName}' in message '${messageId}' uses unresolved $ref '${ref}' and was not compared.`
|
|
202655
|
+
);
|
|
202656
|
+
continue;
|
|
202657
|
+
}
|
|
202658
|
+
if (baseField && headField && baseField.type !== headField.type) {
|
|
202659
|
+
addBreakingChange(
|
|
202660
|
+
"PAYLOAD_FIELD_TYPE_CHANGED",
|
|
202661
|
+
`${pathPrefix}.${fieldName}`,
|
|
202662
|
+
`Payload field '${fieldName}' in message '${messageId}' changed type from '${baseField.type}' to '${headField.type}'.`
|
|
202663
|
+
);
|
|
202664
|
+
continue;
|
|
202665
|
+
}
|
|
202666
|
+
if (baseField && headField && Array.isArray(baseField.enum) && Array.isArray(headField.enum)) {
|
|
202667
|
+
for (const val of baseField.enum) {
|
|
202668
|
+
if (!headField.enum.includes(val)) {
|
|
202669
|
+
addBreakingChange(
|
|
202670
|
+
"ENUM_VALUE_REMOVED",
|
|
202671
|
+
`${pathPrefix}.${fieldName}.${val}`,
|
|
202672
|
+
`Enum value '${val}' was removed from field '${fieldName}' in message '${messageId}'.`
|
|
202673
|
+
);
|
|
202674
|
+
}
|
|
202675
|
+
}
|
|
202676
|
+
for (const val of headField.enum) {
|
|
202677
|
+
if (!baseField.enum.includes(val)) {
|
|
202678
|
+
addNonBreakingChange(
|
|
202679
|
+
"ENUM_VALUE_ADDED",
|
|
202680
|
+
`${pathPrefix}.${fieldName}.${val}`,
|
|
202681
|
+
`New enum value '${val}' was added to field '${fieldName}' in message '${messageId}'.`
|
|
202682
|
+
);
|
|
202683
|
+
}
|
|
202684
|
+
}
|
|
202685
|
+
}
|
|
202686
|
+
if (baseField && headField && (baseField.properties || headField.properties || baseField.type === "object" || headField.type === "object")) {
|
|
202687
|
+
comparePayload(baseField, headField, `${pathPrefix}.${fieldName}`, messageId, baseRoot, headRoot, addBreakingChange, addNonBreakingChange);
|
|
202688
|
+
}
|
|
202689
|
+
}
|
|
202690
|
+
for (const fieldName in headProps) {
|
|
202691
|
+
if (!baseProps[fieldName]) {
|
|
202692
|
+
const addedIsRequired = headReq.has(fieldName);
|
|
202693
|
+
if (!addedIsRequired) {
|
|
202694
|
+
addNonBreakingChange(
|
|
202695
|
+
"PAYLOAD_FIELD_ADDED",
|
|
202696
|
+
`${pathPrefix}.${fieldName}`,
|
|
202697
|
+
`New optional payload field '${fieldName}' was added to message '${messageId}'.`
|
|
202698
|
+
);
|
|
202699
|
+
}
|
|
202700
|
+
}
|
|
202701
|
+
}
|
|
201565
202702
|
}
|
|
201566
202703
|
function diffAsyncAPISchemas(base_schema_content, head_schema_content) {
|
|
201567
202704
|
const base = parseAsyncAPI(base_schema_content);
|
|
@@ -201601,42 +202738,17 @@ var require_asyncapi_diff = __commonJS({
|
|
|
201601
202738
|
}
|
|
201602
202739
|
const basePayload = baseMessage.payload;
|
|
201603
202740
|
const headPayload = headMessage.payload;
|
|
201604
|
-
if (basePayload && headPayload
|
|
201605
|
-
|
|
201606
|
-
|
|
201607
|
-
|
|
201608
|
-
|
|
201609
|
-
|
|
201610
|
-
|
|
201611
|
-
|
|
201612
|
-
|
|
201613
|
-
|
|
201614
|
-
|
|
201615
|
-
addBreakingChange("ENUM_VALUE_REMOVED", `${channelName}.${opType}.${messageId}.${fieldName}.${val}`, `Enum value '${val}' was removed from field '${fieldName}' in message '${messageId}'.`);
|
|
201616
|
-
}
|
|
201617
|
-
}
|
|
201618
|
-
for (const val of headField.enum) {
|
|
201619
|
-
if (!baseField.enum.includes(val)) {
|
|
201620
|
-
addNonBreakingChange("ENUM_VALUE_ADDED", `${channelName}.${opType}.${messageId}.${fieldName}.${val}`, `New enum value '${val}' was added to field '${fieldName}' in message '${messageId}'.`);
|
|
201621
|
-
}
|
|
201622
|
-
}
|
|
201623
|
-
}
|
|
201624
|
-
}
|
|
201625
|
-
for (const fieldName in headPayload.properties) {
|
|
201626
|
-
if (!basePayload.properties[fieldName]) {
|
|
201627
|
-
const addedIsRequired = Array.isArray(headPayload.required) && headPayload.required.includes(fieldName);
|
|
201628
|
-
if (!addedIsRequired) {
|
|
201629
|
-
addNonBreakingChange("PAYLOAD_FIELD_ADDED", `${channelName}.${opType}.${messageId}.${fieldName}`, `New optional payload field '${fieldName}' was added to message '${messageId}'.`);
|
|
201630
|
-
}
|
|
201631
|
-
}
|
|
201632
|
-
}
|
|
201633
|
-
if (headPayload.required && Array.isArray(headPayload.required)) {
|
|
201634
|
-
for (const requiredField of headPayload.required) {
|
|
201635
|
-
if (!basePayload.required || !basePayload.required.includes(requiredField)) {
|
|
201636
|
-
addBreakingChange("REQUIRED_PAYLOAD_FIELD_ADDED", `${channelName}.${opType}.${messageId}.${requiredField}`, `Required payload field '${requiredField}' was added to message '${messageId}'.`);
|
|
201637
|
-
}
|
|
201638
|
-
}
|
|
201639
|
-
}
|
|
202741
|
+
if (basePayload && headPayload) {
|
|
202742
|
+
comparePayload(
|
|
202743
|
+
basePayload,
|
|
202744
|
+
headPayload,
|
|
202745
|
+
`${channelName}.${opType}.${messageId}`,
|
|
202746
|
+
messageId,
|
|
202747
|
+
base.root,
|
|
202748
|
+
head.root,
|
|
202749
|
+
addBreakingChange,
|
|
202750
|
+
addNonBreakingChange
|
|
202751
|
+
);
|
|
201640
202752
|
}
|
|
201641
202753
|
}
|
|
201642
202754
|
for (const messageId in headOperation.messages) {
|
|
@@ -202399,6 +203511,83 @@ var require_remediation_taxonomy = __commonJS({
|
|
|
202399
203511
|
}
|
|
202400
203512
|
});
|
|
202401
203513
|
|
|
203514
|
+
// ../../src/next-agent-step.js
|
|
203515
|
+
var require_next_agent_step2 = __commonJS({
|
|
203516
|
+
"../../src/next-agent-step.js"(exports2, module2) {
|
|
203517
|
+
"use strict";
|
|
203518
|
+
var NEXT_AGENT_ACTIONS = Object.freeze([
|
|
203519
|
+
"re_preflight",
|
|
203520
|
+
"revert",
|
|
203521
|
+
"migrate",
|
|
203522
|
+
"escalate",
|
|
203523
|
+
"await_approval"
|
|
203524
|
+
]);
|
|
203525
|
+
var NEXT_AGENT_ACTION_SET = new Set(NEXT_AGENT_ACTIONS);
|
|
203526
|
+
function mapChoiceIdToNextAction(id) {
|
|
203527
|
+
const s = String(id == null ? "" : id);
|
|
203528
|
+
if (s === "re_preflight" || s === "re_preflight_deploy") return "re_preflight";
|
|
203529
|
+
if (s === "fix_input") return "re_preflight";
|
|
203530
|
+
if (s === "revert") return "revert";
|
|
203531
|
+
if (s === "migrate") return "migrate";
|
|
203532
|
+
if (s === "escalate") return "escalate";
|
|
203533
|
+
if (s === "obtain_human_approval") return "await_approval";
|
|
203534
|
+
return null;
|
|
203535
|
+
}
|
|
203536
|
+
function projectNextAgentStep(executionAction, requiredAction) {
|
|
203537
|
+
const ea = executionAction != null ? String(executionAction) : "";
|
|
203538
|
+
if (ea === "CONTINUE" || ea === "CONTINUE_WITH_MONITORING") return null;
|
|
203539
|
+
if (ea !== "STOP" && ea !== "REQUEST_APPROVAL") return null;
|
|
203540
|
+
const raObj = requiredAction && typeof requiredAction === "object" ? requiredAction : null;
|
|
203541
|
+
const raStr = typeof requiredAction === "string" ? requiredAction : null;
|
|
203542
|
+
const reason = raObj && raObj.reason_code != null && String(raObj.reason_code) || raObj && raObj.type != null && String(raObj.type) || raStr && raStr.slice(0, 200) || (ea === "REQUEST_APPROVAL" ? "request_approval" : "remediate_or_revert");
|
|
203543
|
+
const resume_condition = raObj && typeof raObj.resume_condition === "string" ? raObj.resume_condition : raStr || "";
|
|
203544
|
+
let action = null;
|
|
203545
|
+
if (ea === "REQUEST_APPROVAL") {
|
|
203546
|
+
action = "await_approval";
|
|
203547
|
+
} else {
|
|
203548
|
+
const choices = raObj && Array.isArray(raObj.choices) ? raObj.choices : [];
|
|
203549
|
+
for (const c of choices) {
|
|
203550
|
+
const id = typeof c === "string" ? c : c && c.id != null ? c.id : null;
|
|
203551
|
+
const mapped = mapChoiceIdToNextAction(id);
|
|
203552
|
+
if (mapped && NEXT_AGENT_ACTION_SET.has(mapped) && mapped !== "await_approval") {
|
|
203553
|
+
action = mapped;
|
|
203554
|
+
break;
|
|
203555
|
+
}
|
|
203556
|
+
}
|
|
203557
|
+
if (!action) {
|
|
203558
|
+
const t = raObj && raObj.type != null ? String(raObj.type) : "";
|
|
203559
|
+
if (t === "re_preflight" || t === "remediate_or_revert" || t === "fix_coverage" || t === "revert") {
|
|
203560
|
+
action = t === "revert" ? "revert" : "re_preflight";
|
|
203561
|
+
} else if (raStr || ea === "STOP") {
|
|
203562
|
+
action = "re_preflight";
|
|
203563
|
+
}
|
|
203564
|
+
}
|
|
203565
|
+
}
|
|
203566
|
+
if (!action || !NEXT_AGENT_ACTION_SET.has(action)) return null;
|
|
203567
|
+
let then_call = null;
|
|
203568
|
+
if (action === "re_preflight" || action === "revert" || action === "migrate") {
|
|
203569
|
+
then_call = "preflight_change_set";
|
|
203570
|
+
} else if (action === "await_approval") {
|
|
203571
|
+
then_call = null;
|
|
203572
|
+
} else if (action === "escalate") {
|
|
203573
|
+
then_call = null;
|
|
203574
|
+
}
|
|
203575
|
+
return {
|
|
203576
|
+
action,
|
|
203577
|
+
reason: String(reason),
|
|
203578
|
+
resume_condition: String(resume_condition),
|
|
203579
|
+
then_call
|
|
203580
|
+
};
|
|
203581
|
+
}
|
|
203582
|
+
module2.exports = {
|
|
203583
|
+
NEXT_AGENT_ACTIONS,
|
|
203584
|
+
NEXT_AGENT_ACTION_SET,
|
|
203585
|
+
mapChoiceIdToNextAction,
|
|
203586
|
+
projectNextAgentStep
|
|
203587
|
+
};
|
|
203588
|
+
}
|
|
203589
|
+
});
|
|
203590
|
+
|
|
202402
203591
|
// ../../src/response-envelope.js
|
|
202403
203592
|
var require_response_envelope = __commonJS({
|
|
202404
203593
|
"../../src/response-envelope.js"(exports2, module2) {
|
|
@@ -202642,70 +203831,10 @@ var require_response_envelope = __commonJS({
|
|
|
202642
203831
|
function buildEnforcementDescriptor() {
|
|
202643
203832
|
return { ...ENFORCEMENT_DESCRIPTOR };
|
|
202644
203833
|
}
|
|
202645
|
-
var
|
|
202646
|
-
|
|
202647
|
-
|
|
202648
|
-
|
|
202649
|
-
"escalate",
|
|
202650
|
-
"await_approval"
|
|
202651
|
-
]);
|
|
202652
|
-
var NEXT_AGENT_ACTION_SET = new Set(NEXT_AGENT_ACTIONS);
|
|
202653
|
-
function mapChoiceIdToNextAction(id) {
|
|
202654
|
-
const s = String(id == null ? "" : id);
|
|
202655
|
-
if (s === "re_preflight" || s === "re_preflight_deploy") return "re_preflight";
|
|
202656
|
-
if (s === "fix_input") return "re_preflight";
|
|
202657
|
-
if (s === "revert") return "revert";
|
|
202658
|
-
if (s === "migrate") return "migrate";
|
|
202659
|
-
if (s === "escalate") return "escalate";
|
|
202660
|
-
if (s === "obtain_human_approval") return "await_approval";
|
|
202661
|
-
return null;
|
|
202662
|
-
}
|
|
202663
|
-
function projectNextAgentStep(executionAction, requiredAction) {
|
|
202664
|
-
const ea = executionAction != null ? String(executionAction) : "";
|
|
202665
|
-
if (ea === "CONTINUE" || ea === "CONTINUE_WITH_MONITORING") return null;
|
|
202666
|
-
if (ea !== "STOP" && ea !== "REQUEST_APPROVAL") return null;
|
|
202667
|
-
const raObj = requiredAction && typeof requiredAction === "object" ? requiredAction : null;
|
|
202668
|
-
const raStr = typeof requiredAction === "string" ? requiredAction : null;
|
|
202669
|
-
const reason = raObj && raObj.reason_code != null && String(raObj.reason_code) || raObj && raObj.type != null && String(raObj.type) || raStr && raStr.slice(0, 200) || (ea === "REQUEST_APPROVAL" ? "request_approval" : "remediate_or_revert");
|
|
202670
|
-
const resume_condition = raObj && typeof raObj.resume_condition === "string" ? raObj.resume_condition : raStr || "";
|
|
202671
|
-
let action = null;
|
|
202672
|
-
if (ea === "REQUEST_APPROVAL") {
|
|
202673
|
-
action = "await_approval";
|
|
202674
|
-
} else {
|
|
202675
|
-
const choices = raObj && Array.isArray(raObj.choices) ? raObj.choices : [];
|
|
202676
|
-
for (const c of choices) {
|
|
202677
|
-
const id = typeof c === "string" ? c : c && c.id != null ? c.id : null;
|
|
202678
|
-
const mapped = mapChoiceIdToNextAction(id);
|
|
202679
|
-
if (mapped && NEXT_AGENT_ACTION_SET.has(mapped) && mapped !== "await_approval") {
|
|
202680
|
-
action = mapped;
|
|
202681
|
-
break;
|
|
202682
|
-
}
|
|
202683
|
-
}
|
|
202684
|
-
if (!action) {
|
|
202685
|
-
const t = raObj && raObj.type != null ? String(raObj.type) : "";
|
|
202686
|
-
if (t === "re_preflight" || t === "remediate_or_revert" || t === "fix_coverage" || t === "revert") {
|
|
202687
|
-
action = t === "revert" ? "revert" : "re_preflight";
|
|
202688
|
-
} else if (raStr || ea === "STOP") {
|
|
202689
|
-
action = "re_preflight";
|
|
202690
|
-
}
|
|
202691
|
-
}
|
|
202692
|
-
}
|
|
202693
|
-
if (!action || !NEXT_AGENT_ACTION_SET.has(action)) return null;
|
|
202694
|
-
let then_call = null;
|
|
202695
|
-
if (action === "re_preflight" || action === "revert" || action === "migrate") {
|
|
202696
|
-
then_call = "preflight_change_set";
|
|
202697
|
-
} else if (action === "await_approval") {
|
|
202698
|
-
then_call = null;
|
|
202699
|
-
} else if (action === "escalate") {
|
|
202700
|
-
then_call = null;
|
|
202701
|
-
}
|
|
202702
|
-
return {
|
|
202703
|
-
action,
|
|
202704
|
-
reason: String(reason),
|
|
202705
|
-
resume_condition: String(resume_condition),
|
|
202706
|
-
then_call
|
|
202707
|
-
};
|
|
202708
|
-
}
|
|
203834
|
+
var {
|
|
203835
|
+
NEXT_AGENT_ACTIONS,
|
|
203836
|
+
projectNextAgentStep
|
|
203837
|
+
} = require_next_agent_step2();
|
|
202709
203838
|
function buildControlEnvelope(verdict, authzContext) {
|
|
202710
203839
|
const receipt_view = projectReceipt(verdict, authzContext);
|
|
202711
203840
|
let safeForAgent = verdict.safe_for_agent;
|
|
@@ -202829,6 +203958,7 @@ var require_response_envelope = __commonJS({
|
|
|
202829
203958
|
return response;
|
|
202830
203959
|
}
|
|
202831
203960
|
response.control_envelope = buildControlEnvelope(response, authzContext);
|
|
203961
|
+
if (isCoverageFailClosed(response)) response.safe_for_agent = false;
|
|
202832
203962
|
response.analysis = buildAnalysisTier(response);
|
|
202833
203963
|
try {
|
|
202834
203964
|
response.analysis.remediations = buildRemediations(response);
|
|
@@ -204396,6 +205526,48 @@ var require_decision_result_v1_producer = __commonJS({
|
|
|
204396
205526
|
}
|
|
204397
205527
|
}
|
|
204398
205528
|
},
|
|
205529
|
+
next_agent_step: {
|
|
205530
|
+
type: [
|
|
205531
|
+
"object",
|
|
205532
|
+
"null"
|
|
205533
|
+
],
|
|
205534
|
+
additionalProperties: false,
|
|
205535
|
+
required: [
|
|
205536
|
+
"action",
|
|
205537
|
+
"reason",
|
|
205538
|
+
"resume_condition",
|
|
205539
|
+
"then_call"
|
|
205540
|
+
],
|
|
205541
|
+
description: "Additive (I-1288). The decision's own remediation SUGGESTION, projected at issuance from execution_action + required_action_core \u2014 the identical pure function that fills control_envelope.next_agent_step (src/next-agent-step.js). One projection, two placements, never two rules. INSIDE the envelope it is covered by decision_body_hash, so the signed receipt covers the suggestion along with the decision that produced it: a consumer handed only the envelope (k8s-admission, gateway-verifier, agent-guard deployGate) can render the next step without a second call to the issuer, and a tampered step no longer verifies. NOT PERMISSION and NOT a control-flow override \u2014 branch on execution_action. null on the allow class (CONTINUE / CONTINUE_WITH_MONITORING) is the correct value, not a missing measurement; null also on legacy non-additive envelopes, which never carry the field.",
|
|
205542
|
+
properties: {
|
|
205543
|
+
action: {
|
|
205544
|
+
type: "string",
|
|
205545
|
+
enum: [
|
|
205546
|
+
"re_preflight",
|
|
205547
|
+
"revert",
|
|
205548
|
+
"migrate",
|
|
205549
|
+
"escalate",
|
|
205550
|
+
"await_approval"
|
|
205551
|
+
],
|
|
205552
|
+
description: "Closed set \u2014 src/next-agent-step.js NEXT_AGENT_ACTIONS."
|
|
205553
|
+
},
|
|
205554
|
+
reason: {
|
|
205555
|
+
type: "string",
|
|
205556
|
+
description: "required_action reason_code / type, or the display string when that is all the issuance path had."
|
|
205557
|
+
},
|
|
205558
|
+
resume_condition: {
|
|
205559
|
+
type: "string",
|
|
205560
|
+
description: "What must hold before the caller retries. Projected from the FROZEN required_action_core, which carries no receipt-authz overlay, so this is the one subfield that may be thinner than control_envelope.next_agent_step.resume_condition (the live surface projects from deriveRequiredAction, which has the overlay and can name the approval receipt it wants). Signing the overlay text would sign a fact the envelope deliberately excludes. Empty string when the frozen core supplied none \u2014 not an error."
|
|
205561
|
+
},
|
|
205562
|
+
then_call: {
|
|
205563
|
+
type: [
|
|
205564
|
+
"string",
|
|
205565
|
+
"null"
|
|
205566
|
+
],
|
|
205567
|
+
description: "Tool to call after the step, or null when the next move is a human one."
|
|
205568
|
+
}
|
|
205569
|
+
}
|
|
205570
|
+
},
|
|
204399
205571
|
remediation_transaction: {
|
|
204400
205572
|
type: [
|
|
204401
205573
|
"object",
|
|
@@ -205090,6 +206262,174 @@ var require_decision_result_validator = __commonJS({
|
|
|
205090
206262
|
}
|
|
205091
206263
|
});
|
|
205092
206264
|
|
|
206265
|
+
// ../../schemas/execution-grant-request.v2.producer.json
|
|
206266
|
+
var require_execution_grant_request_v2_producer = __commonJS({
|
|
206267
|
+
"../../schemas/execution-grant-request.v2.producer.json"(exports2, module2) {
|
|
206268
|
+
module2.exports = {
|
|
206269
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
206270
|
+
$id: "https://coderifts.com/schemas/execution-grant-request.v2.producer.json",
|
|
206271
|
+
title: "CodeRifts Execution Grant Request v2 \u2014 PRODUCER schema",
|
|
206272
|
+
description: "Execution-grant REQUEST v2 \u2014 the fields the authorize handler actually reads when minting a cr.exec.v2 grant. Measured from src/change-set.js:1209-1285 (the wantGrant/wantV2 block) plus the operation / audience / environment reads that same handler already performs, and pinned field-by-field by test/fixtures/v2-grant-field-matrix.json. PRODUCER-ONLY, DELIBERATELY. The pairing convention in schemas/ is not universal: decision-result.v1 and preflight-response.v2 have consumer twins because a GENERATOR derives one from the other (scripts/generate-consumer-schema.js), while control-envelope.v1 and verify-receipt.v1 are producer-only. No generator derives a request consumer, and the only thing a consumer twin would say differently is `additionalProperties`, which is stated here directly. A second hand-maintained file whose sole difference is one keyword is a drift risk, not a contract. ROLES ARE INVERTED relative to the response schemas: on a REQUEST the CLIENT is the producer and the SERVER is the consumer. `additionalProperties` is therefore TRUE, and that is a measurement of current behaviour, not an aspiration \u2014 the handler reads named fields off `input` and ignores everything else, so a client sending an extra key is accepted today. Validation is advisory by default (EXECUTION_GRANT_REQUEST_VALIDATOR_MODE=log); nothing in this schema starts rejecting a request that works now. NOT REQUEST FIELDS \u2014 MINTED BY THE ISSUER, and excluded on purpose: `jti`, `expires_at` / `expiry`, `after_payload_digest` (plus `kid`, `grant_id`, `receipt_hash`, `nonce_hash`, `not_before`, `max_attempts`). src/verdict-core/execution-grant-v2.js:110-154 derives every one of them from the signed receipt and the change set. A caller cannot supply them and the handler would not read them; listing them here would describe a request surface that does not exist. BOUND SINCE 1206 VARIANT A \u2014 `policy_hash` and `audience_hash`: both are now carried into the signed grant. `policy_hash` is forwarded by the authorize handler (src/change-set.js:1323) into the issuer, which binds it at src/verdict-core/execution-grant-v2.js:149; a verifier that states `intended.policy_hash` gets a GRANT_UNBOUND/policy_mismatch on a mismatch. `audience_hash` is NOT a request field of its own: it is derived from `audience` (execution-grant-v2.js:150) and was already enforced (:227-234), so sending it separately has no effect and it stays out of this schema. Before this change policy_hash was accepted on the wire and dropped at the handler, which minted every grant under the sha256('') default \u2014 a field that looked bound and was not.",
|
|
206273
|
+
type: "object",
|
|
206274
|
+
additionalProperties: true,
|
|
206275
|
+
required: [
|
|
206276
|
+
"include_execution_grant"
|
|
206277
|
+
],
|
|
206278
|
+
properties: {
|
|
206279
|
+
include_execution_grant: {
|
|
206280
|
+
type: "boolean",
|
|
206281
|
+
description: 'Gates the whole grant path. src/change-set.js:1209 \u2014 strictly `=== true`, so any other value (including the string "true") mints no grant.'
|
|
206282
|
+
},
|
|
206283
|
+
grant_version: {
|
|
206284
|
+
type: "string",
|
|
206285
|
+
enum: [
|
|
206286
|
+
"v1",
|
|
206287
|
+
"v2"
|
|
206288
|
+
],
|
|
206289
|
+
description: "src/change-set.js:1268 \u2014 `v2` selects the cr.exec.v2 issuer. Absent or any other value takes the v1 branch. `grantVersion` (camelCase) is accepted as an alias at the same line; both are listed so neither reads as undeclared."
|
|
206290
|
+
},
|
|
206291
|
+
grantVersion: {
|
|
206292
|
+
type: "string",
|
|
206293
|
+
enum: [
|
|
206294
|
+
"v1",
|
|
206295
|
+
"v2"
|
|
206296
|
+
],
|
|
206297
|
+
description: "camelCase alias of grant_version, read at src/change-set.js:1268. Declared because the handler reads it, not because it is recommended."
|
|
206298
|
+
},
|
|
206299
|
+
tenant_id: {
|
|
206300
|
+
type: "string",
|
|
206301
|
+
minLength: 1,
|
|
206302
|
+
description: "src/change-set.js:1279 \u2014 `input.tenant_id || context.tenant_id || 'default'`. The default is a real value, not an absence: an unset tenant is issued as `default`, it is not left unbound."
|
|
206303
|
+
},
|
|
206304
|
+
executor_id: {
|
|
206305
|
+
type: "string",
|
|
206306
|
+
minLength: 1,
|
|
206307
|
+
description: "src/change-set.js:1277 \u2014 `input.executor_id || context.executor_id || 'local'`."
|
|
206308
|
+
},
|
|
206309
|
+
adapter_id: {
|
|
206310
|
+
type: "string",
|
|
206311
|
+
minLength: 1,
|
|
206312
|
+
description: "src/change-set.js:1278 \u2014 `input.adapter_id || context.adapter_id || 'fs'`."
|
|
206313
|
+
},
|
|
206314
|
+
target_uri: {
|
|
206315
|
+
type: "string",
|
|
206316
|
+
minLength: 1,
|
|
206317
|
+
description: "src/change-set.js:1276 \u2014 `input.target_uri || context.target_uri`, else a derived `git://{context.repository||'local/repo'}@{context.head_sha||'unknown'}`. The derived form is a fallback, not a binding the caller asked for."
|
|
206318
|
+
},
|
|
206319
|
+
state_nonce: {
|
|
206320
|
+
type: "string",
|
|
206321
|
+
minLength: 1,
|
|
206322
|
+
description: "src/change-set.js:1265-1267 \u2014 non-empty string only; anything else becomes null and the grant is issued without a nonce."
|
|
206323
|
+
},
|
|
206324
|
+
expected_state_token: {
|
|
206325
|
+
type: "string",
|
|
206326
|
+
description: "src/change-set.js:1281 \u2014 `nonEmptyStr(input.expected_state_token) || ''`. Empty string is the issued value when absent; there is no unbound state."
|
|
206327
|
+
},
|
|
206328
|
+
audience: {
|
|
206329
|
+
type: "string",
|
|
206330
|
+
pattern: "^v:[0-9a-f]{12}$",
|
|
206331
|
+
description: "src/change-set.js:1120-1124 \u2014 ONLY the measured `v:<12 hex>` form is accepted; any other string is discarded to null rather than trusted as identity. A free-form caller-supplied name is never an audience."
|
|
206332
|
+
},
|
|
206333
|
+
policy_hash: {
|
|
206334
|
+
type: "string",
|
|
206335
|
+
minLength: 1,
|
|
206336
|
+
description: "src/change-set.js:1305 \u2014 the policy identity this request is made under, bound into the signed grant (execution-grant-v2.js:149). A value already prefixed `sha256:` is carried through; anything else is hashed. Absent \u2192 the issuer's sha256('') default, which is what every grant carried before 1206 variant A. Enforced only by a verifier that states intended.policy_hash \u2014 binding is not by itself a check."
|
|
206337
|
+
},
|
|
206338
|
+
context: {
|
|
206339
|
+
type: "object",
|
|
206340
|
+
additionalProperties: true,
|
|
206341
|
+
description: "The request context object (src/change-set.js:806). Only the keys the grant path reads are declared; the handler reads many others for unrelated purposes and tolerates the rest, so additionalProperties stays true here for the same reason it does at the root.",
|
|
206342
|
+
properties: {
|
|
206343
|
+
operation: {
|
|
206344
|
+
type: "string",
|
|
206345
|
+
minLength: 1,
|
|
206346
|
+
description: "src/change-set.js:807-812 \u2014 REQUIRED for preflight_mode=authorize; the handler throws a typed input error without one. Authorization asks permission for a named operation."
|
|
206347
|
+
},
|
|
206348
|
+
environment: {
|
|
206349
|
+
type: "string",
|
|
206350
|
+
description: "src/change-set.js:1159 \u2014 carried onto the envelope. Not a grant field; read by the same handler on the same request."
|
|
206351
|
+
},
|
|
206352
|
+
target_id: {
|
|
206353
|
+
type: "string",
|
|
206354
|
+
description: "src/change-set.js:1264 \u2014 v1 grant target fallback; the v2 branch uses target_uri instead."
|
|
206355
|
+
},
|
|
206356
|
+
target_uri: {
|
|
206357
|
+
type: "string",
|
|
206358
|
+
description: "src/change-set.js:1276 \u2014 fallback when input.target_uri is absent."
|
|
206359
|
+
},
|
|
206360
|
+
executor_id: {
|
|
206361
|
+
type: "string",
|
|
206362
|
+
description: "src/change-set.js:1277 \u2014 fallback when input.executor_id is absent."
|
|
206363
|
+
},
|
|
206364
|
+
adapter_id: {
|
|
206365
|
+
type: "string",
|
|
206366
|
+
description: "src/change-set.js:1278 \u2014 fallback when input.adapter_id is absent."
|
|
206367
|
+
},
|
|
206368
|
+
tenant_id: {
|
|
206369
|
+
type: "string",
|
|
206370
|
+
description: "src/change-set.js:1279 \u2014 fallback when input.tenant_id is absent."
|
|
206371
|
+
},
|
|
206372
|
+
repository: {
|
|
206373
|
+
type: "string",
|
|
206374
|
+
description: "src/change-set.js:1276 \u2014 feeds the DERIVED target_uri when no explicit one was supplied."
|
|
206375
|
+
},
|
|
206376
|
+
head_sha: {
|
|
206377
|
+
type: "string",
|
|
206378
|
+
description: "src/change-set.js:1276 \u2014 feeds the DERIVED target_uri when no explicit one was supplied."
|
|
206379
|
+
}
|
|
206380
|
+
}
|
|
206381
|
+
}
|
|
206382
|
+
},
|
|
206383
|
+
$comment: "Field set pinned by test/fixtures/v2-grant-field-matrix.json (schema column) and test/execution-grant-request-schema.test.js. Adding a property here without adding the matching matrix cell fails the drift gate."
|
|
206384
|
+
};
|
|
206385
|
+
}
|
|
206386
|
+
});
|
|
206387
|
+
|
|
206388
|
+
// ../../src/execution-grant-request-validator.js
|
|
206389
|
+
var require_execution_grant_request_validator = __commonJS({
|
|
206390
|
+
"../../src/execution-grant-request-validator.js"(exports2, module2) {
|
|
206391
|
+
"use strict";
|
|
206392
|
+
var Ajv2020 = require__();
|
|
206393
|
+
var requestSchema = require_execution_grant_request_v2_producer();
|
|
206394
|
+
var ajv = new Ajv2020({ strict: false, allErrors: true });
|
|
206395
|
+
var _validate = ajv.compile(requestSchema);
|
|
206396
|
+
function isV2GrantRequest(input) {
|
|
206397
|
+
if (!input || typeof input !== "object") return false;
|
|
206398
|
+
if (input.include_execution_grant !== true) return false;
|
|
206399
|
+
return input.grant_version === "v2" || input.grantVersion === "v2";
|
|
206400
|
+
}
|
|
206401
|
+
function validateExecutionGrantRequest(input) {
|
|
206402
|
+
const valid = _validate(input);
|
|
206403
|
+
return { valid: !!valid, errors: valid ? [] : _validate.errors || [] };
|
|
206404
|
+
}
|
|
206405
|
+
function validatorMode() {
|
|
206406
|
+
return process.env.EXECUTION_GRANT_REQUEST_VALIDATOR_MODE === "enforce" ? "enforce" : "log";
|
|
206407
|
+
}
|
|
206408
|
+
function guardExecutionGrantRequest(input, { logger } = {}) {
|
|
206409
|
+
if (!isV2GrantRequest(input)) return { ok: true, skipped: true };
|
|
206410
|
+
const { valid, errors } = validateExecutionGrantRequest(input);
|
|
206411
|
+
if (valid) return { ok: true };
|
|
206412
|
+
const error = { code: "GRANT_REQUEST_SCHEMA_VALIDATION_FAILED", errors };
|
|
206413
|
+
if (validatorMode() === "enforce") {
|
|
206414
|
+
return { ok: false, error };
|
|
206415
|
+
}
|
|
206416
|
+
if (logger && typeof logger.warn === "function") {
|
|
206417
|
+
logger.warn(
|
|
206418
|
+
{ severity: "MEDIUM", event: "execution_grant_request_schema_violation", errors },
|
|
206419
|
+
"v2 execution-grant request failed producer-schema validation (log mode \u2014 the request proceeds unchanged)"
|
|
206420
|
+
);
|
|
206421
|
+
}
|
|
206422
|
+
return { ok: true };
|
|
206423
|
+
}
|
|
206424
|
+
module2.exports = {
|
|
206425
|
+
validateExecutionGrantRequest,
|
|
206426
|
+
guardExecutionGrantRequest,
|
|
206427
|
+
isV2GrantRequest,
|
|
206428
|
+
validatorMode
|
|
206429
|
+
};
|
|
206430
|
+
}
|
|
206431
|
+
});
|
|
206432
|
+
|
|
205093
206433
|
// ../../src/source-binding-gate.js
|
|
205094
206434
|
var require_source_binding_gate = __commonJS({
|
|
205095
206435
|
"../../src/source-binding-gate.js"(exports2, module2) {
|
|
@@ -206092,6 +207432,13 @@ var require_execution_grant_v2 = __commonJS({
|
|
|
206092
207432
|
if (intended.audience_hash != null && String(intended.audience_hash).length > 0 && payload.audience_hash !== String(intended.audience_hash)) {
|
|
206093
207433
|
return { valid: false, status: "GRANT_UNBOUND", reason: "audience_mismatch", payload };
|
|
206094
207434
|
}
|
|
207435
|
+
if (intended.policy_hash != null && String(intended.policy_hash).length > 0) {
|
|
207436
|
+
const wantPolicy = String(intended.policy_hash);
|
|
207437
|
+
const norm = wantPolicy.startsWith("sha256:") ? wantPolicy : sha256pref(wantPolicy);
|
|
207438
|
+
if (payload.policy_hash !== norm) {
|
|
207439
|
+
return { valid: false, status: "GRANT_UNBOUND", reason: "policy_mismatch", payload };
|
|
207440
|
+
}
|
|
207441
|
+
}
|
|
206095
207442
|
if (intended.after_payload != null) {
|
|
206096
207443
|
if (payload.after_payload_hash !== sha256pref(intended.after_payload)) {
|
|
206097
207444
|
return { valid: false, status: "GRANT_UNBOUND", reason: "after_payload_mismatch", payload };
|
|
@@ -206528,6 +207875,7 @@ var require_change_set = __commonJS({
|
|
|
206528
207875
|
var { buildDecisionResultV1 } = require_decision_result();
|
|
206529
207876
|
var { deriveRequiredAction } = require_response_envelope();
|
|
206530
207877
|
var { guardDecisionResult } = require_decision_result_validator();
|
|
207878
|
+
var { guardExecutionGrantRequest } = require_execution_grant_request_validator();
|
|
206531
207879
|
var { issueReceipt, isConfigured, sha256hex } = require_chain_attestation();
|
|
206532
207880
|
var { getPatternConfigHash } = require_omega_scoring();
|
|
206533
207881
|
var { computeBlastRadiusCounts } = require_blast_radius_counts();
|
|
@@ -207399,6 +208747,16 @@ var require_change_set = __commonJS({
|
|
|
207399
208747
|
}
|
|
207400
208748
|
const authorizeAction = preflightMode === "authorize" ? deriveExecutionAction(core.decision) : null;
|
|
207401
208749
|
const allowClass = authorizeAction === "CONTINUE" || authorizeAction === "CONTINUE_WITH_MONITORING";
|
|
208750
|
+
if (preflightMode === "authorize" && wantGrant) {
|
|
208751
|
+
const reqGuard = guardExecutionGrantRequest(input, { logger });
|
|
208752
|
+
if (!reqGuard.ok) {
|
|
208753
|
+
throw typedError(
|
|
208754
|
+
reqGuard.error.code,
|
|
208755
|
+
"execution-grant request failed producer-schema validation",
|
|
208756
|
+
{ errors: reqGuard.error.errors }
|
|
208757
|
+
);
|
|
208758
|
+
}
|
|
208759
|
+
}
|
|
207402
208760
|
if (preflightMode === "authorize" && wantGrant && allowClass && typeof receipt === "string" && receipt.length > 0) {
|
|
207403
208761
|
try {
|
|
207404
208762
|
const {
|
|
@@ -207420,7 +208778,25 @@ var require_change_set = __commonJS({
|
|
|
207420
208778
|
adapter_id: nonEmptyStr(input.adapter_id) || nonEmptyStr(context.adapter_id) || "fs",
|
|
207421
208779
|
tenant_id: nonEmptyStr(input.tenant_id) || nonEmptyStr(context.tenant_id) || "default",
|
|
207422
208780
|
nonce: stateNonce,
|
|
207423
|
-
expected_state_token: nonEmptyStr(input.expected_state_token) || ""
|
|
208781
|
+
expected_state_token: nonEmptyStr(input.expected_state_token) || "",
|
|
208782
|
+
// 1206 variant A — the caller's claimed policy identity, BOUND into the signed grant.
|
|
208783
|
+
//
|
|
208784
|
+
// It was the one v2 field a client could send and the server would drop: the issuer
|
|
208785
|
+
// has always read args.policy_hash (verdict-core/execution-grant-v2.js:132) and the
|
|
208786
|
+
// wire has always carried a policy_hash slot, but this handler never forwarded it, so
|
|
208787
|
+
// every grant was minted with the sha256('') default. A field that looks bound and is
|
|
208788
|
+
// not is worse than an absent one — a reader of the token cannot tell the difference.
|
|
208789
|
+
//
|
|
208790
|
+
// AUDIENCE NEEDS NO LINE HERE: `audience` is already passed at the top of this call
|
|
208791
|
+
// and the issuer derives audience_hash from it (:150), which the verifier already
|
|
208792
|
+
// enforces (:227-234). Only policy_hash was missing.
|
|
208793
|
+
//
|
|
208794
|
+
// This binds what the CALLER CLAIMS, which is the whole point: the grant becomes
|
|
208795
|
+
// tamper-evident about the policy it was issued under, and a verifier that knows which
|
|
208796
|
+
// policy it expects can refuse a mismatch (intended.policy_hash, added symmetrically
|
|
208797
|
+
// to the existing intended.audience_hash check). Absent → the issuer's sha256('')
|
|
208798
|
+
// default, exactly as before.
|
|
208799
|
+
policy_hash: nonEmptyStr(input.policy_hash) || void 0
|
|
207424
208800
|
} : {
|
|
207425
208801
|
target_id: grantTarget,
|
|
207426
208802
|
...stateNonce ? { state_nonce: stateNonce } : {}
|
|
@@ -220480,6 +221856,15 @@ var require_persist_decision = __commonJS({
|
|
|
220480
221856
|
return null;
|
|
220481
221857
|
}
|
|
220482
221858
|
}
|
|
221859
|
+
function persistMeta(decisionId) {
|
|
221860
|
+
if (typeof decisionId === "string" && decisionId.length > 0) {
|
|
221861
|
+
return { stored: true };
|
|
221862
|
+
}
|
|
221863
|
+
return {
|
|
221864
|
+
stored: false,
|
|
221865
|
+
reason: persistenceEnabled() ? "storage_unavailable" : "persistence_disabled"
|
|
221866
|
+
};
|
|
221867
|
+
}
|
|
220483
221868
|
var AFTER_HEX_RE = /^[0-9a-f]{64}$/;
|
|
220484
221869
|
function normalizeAfterHex(raw) {
|
|
220485
221870
|
if (raw == null) return "";
|
|
@@ -220862,6 +222247,8 @@ var require_persist_decision = __commonJS({
|
|
|
220862
222247
|
}
|
|
220863
222248
|
module2.exports = {
|
|
220864
222249
|
persistDecision,
|
|
222250
|
+
persistMeta,
|
|
222251
|
+
persistenceEnabled,
|
|
220865
222252
|
persistAuthorizedPaths,
|
|
220866
222253
|
findDecisionsByAfterHash,
|
|
220867
222254
|
getAuthorizedPathsCollectingSince,
|
|
@@ -223317,82 +224704,7 @@ var require_mcp_streamable = __commonJS({
|
|
|
223317
224704
|
});
|
|
223318
224705
|
next();
|
|
223319
224706
|
});
|
|
223320
|
-
var DESC_PREFLIGHT_CHANGE_SET =
|
|
223321
|
-
risk score and breaking-change analysis \u2014 plus, on the AUTHORIZE path only, a governance decision
|
|
223322
|
-
(ALLOW / WARN / REQUIRE_APPROVAL / BLOCK) and a signed chain-receipt when applicable. ANALYZE
|
|
223323
|
-
returns informational risk only: analysis_outcome, may_execute:false, no decision, no receipt.
|
|
223324
|
-
|
|
223325
|
-
Requires a pending base\u2192head (before/after) contract change you are about to
|
|
223326
|
-
act on (merge, deploy, publish, or register tools). No pending change set \u2192
|
|
223327
|
-
do not call this tool.
|
|
223328
|
-
|
|
223329
|
-
Use this when:
|
|
223330
|
-
- You are about to merge, push, deploy, publish, or register/expose agent tools,
|
|
223331
|
-
AND the change includes \u22651 contract artifact (OpenAPI/Swagger, GraphQL SDL,
|
|
223332
|
-
gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas: type=agent_tools,
|
|
223333
|
-
including before re-registering tools with a runtime).
|
|
223334
|
-
- You have (or can assemble) FULL base and head for every changed contract
|
|
223335
|
-
artifact in this set \u2014 not a single-file subset when other contract files also
|
|
223336
|
-
change.
|
|
223337
|
-
- You need a NEW decision for the CURRENT change; you do not already hold a
|
|
223338
|
-
currently-valid receipt for this exact target/operation.
|
|
223339
|
-
- You hold a receipt for a different operation or target than the act you will
|
|
223340
|
-
perform (e.g. ALLOW for merge, now deploying). A receipt authorizes ONE
|
|
223341
|
-
operation: a merge receipt does not authorize a deploy. Run a NEW preflight
|
|
223342
|
-
with context.operation set to that operation (deploy, publish); a
|
|
223343
|
-
differently-scoped receipt is not reusable authorization and will fail at
|
|
223344
|
-
the gate.
|
|
223345
|
-
|
|
223346
|
-
Do not use when:
|
|
223347
|
-
- The change is documentation-only (README, guides, comments) with no contract
|
|
223348
|
-
artifact content change \u2014 do not call any CodeRifts tool.
|
|
223349
|
-
- You already hold a signed receipt and only need to check it is authentic and
|
|
223350
|
-
currently valid \u2014 use coderifts.verify_receipt instead.
|
|
223351
|
-
- You need details of a PREVIOUS decision by decision_id \u2014 use
|
|
223352
|
-
coderifts.get_decision_details instead.
|
|
223353
|
-
- You want a static 0\u2013100 "agent readiness" score for one OpenAPI/MCP file and
|
|
223354
|
-
there is no pending base\u2192head mutate \u2014 use coderifts.agent_readiness_score
|
|
223355
|
-
(advanced / opt-in; not one of the three default tools). If that tool is not
|
|
223356
|
-
in your available list, call none of the CodeRifts tools; do not substitute
|
|
223357
|
-
preflight_change_set.
|
|
223358
|
-
- You cannot supply both before and after (or base and head) for the artifacts
|
|
223359
|
-
that change \u2014 fix the change set first; do not invent empty before specs.
|
|
223360
|
-
|
|
223361
|
-
Inputs: list of artifacts, each with type, before, after (or equivalent), plus
|
|
223362
|
-
optional operation (merge|deploy|tool_call|publish), environment/stakes, and
|
|
223363
|
-
context. Opt-in derivation:"server" (proven tenant\u2194repo binding + context.repository
|
|
223364
|
-
+ base + head): omit artifacts[] \u2014 the server lists the contract-class set via the
|
|
223365
|
-
SCM provider for the proven binding (GitHub App Compare, or GitLab/Bitbucket Compare
|
|
223366
|
-
with a per-request X-Coderifts-Scm-Token, never stored; completeness_mode
|
|
223367
|
-
SERVER_DERIVED). Default (flag absent) is unchanged. Returns decision,
|
|
223368
|
-
execution_action, risk fields, and chain_receipt when issued.
|
|
223369
|
-
|
|
223370
|
-
CHANGE SOURCE \u2014 EXACTLY ONE, ENFORCED AT THE ROUTE (400), NOT BY THIS SCHEMA.
|
|
223371
|
-
Supply either artifacts[] OR derivation:"server". All three of these are rejected
|
|
223372
|
-
with HTTP 400 INVALID_INPUT, on analyze and on authorize alike:
|
|
223373
|
-
\u2022 neither artifacts[] nor derivation \u2192 "artifacts must be a non-empty array"
|
|
223374
|
-
\u2022 authorize with context.operation but no change source \u2192 same 400
|
|
223375
|
-
\u2022 artifacts[] together with derivation:"server" \u2192 "derivation:"server" forbids
|
|
223376
|
-
caller-supplied artifacts[] \u2014 one source of truth per request"
|
|
223377
|
-
This constraint is NOT expressible in the schema you are reading: a top-level
|
|
223378
|
-
oneOf/allOf union is rejected by at least one major MCP client (measured), so the
|
|
223379
|
-
schema stays permissive and the route is the enforcement point. Do not read schema
|
|
223380
|
-
acceptance as request validity \u2014 verified live against these exact three shapes on
|
|
223381
|
-
2026-08-26, over REST and over MCP tools/call (isError:true on all three).
|
|
223382
|
-
|
|
223383
|
-
Mode (required): pass preflight_mode. Use "analyze" for informational risk only
|
|
223384
|
-
(returns analysis_outcome with may_execute:false, no decision/execution_action/
|
|
223385
|
-
safe_for_agent, no receipt). Use "authorize" for the operation-bound path that can
|
|
223386
|
-
mint a receipt (requires context.operation: merge|deploy|publish|tool_call). Under
|
|
223387
|
-
Decision Spec 2.0 the mode is mandatory; omission is an error unless a legacy
|
|
223388
|
-
decision_spec_version "1.0" pin is set.
|
|
223389
|
-
|
|
223390
|
-
Branch on execution_action only (CONTINUE | CONTINUE_WITH_MONITORING | REQUEST_APPROVAL | STOP).
|
|
223391
|
-
On non-CONTINUE authorize responses, control_envelope.next_agent_step is a structured
|
|
223392
|
-
remediation SUGGESTION the agent MAY follow (action, reason, resume_condition, then_call).
|
|
223393
|
-
It is NOT permission and NOT a control-flow override \u2014 still branch on execution_action.
|
|
223394
|
-
On CONTINUE / CONTINUE_WITH_MONITORING, next_agent_step is null (no remediation step).
|
|
223395
|
-
Human tier remains human_report.next_steps_prose (same source; prose, not machine).`;
|
|
224707
|
+
var DESC_PREFLIGHT_CHANGE_SET = "Use this when: a change set of contract artifacts modifies OpenAPI, GraphQL, protobuf, AsyncAPI, MCP manifests, or agent tool schemas before merge, deploy, publish, or tool registration. Do not call for documentation-only changes, static readiness scoring, or receipt verification. Use analyze for risk only; authorize requires context.operation for permission. For receipt verification use coderifts.verify_receipt instead; for details of a past decision use coderifts.get_decision_details instead.";
|
|
223396
224708
|
var DESC_VERIFY_RECEIPT = `Verify a CodeRifts signed chain-receipt you ALREADY HOLD: cryptographic
|
|
223397
224709
|
authenticity (signature + key id), body binding, and \u2014 when lifecycle indices
|
|
223398
224710
|
are available \u2014 whether it is currently valid authorization (not expired,
|
|
@@ -223725,7 +225037,11 @@ next_agent_step is a suggestion, not permission.`;
|
|
|
223725
225037
|
}
|
|
223726
225038
|
}
|
|
223727
225039
|
},
|
|
223728
|
-
|
|
225040
|
+
// Authorize CREATES an authorization (receipt / grant). readOnlyHint:true over-stated
|
|
225041
|
+
// the mixed tool (roadmap 1212). Analyze is still informational (no receipt) — that
|
|
225042
|
+
// is the mode, not this annotation. Split into two tools is deferred: then_call in
|
|
225043
|
+
// response-envelope.js still names preflight_change_set, and the canonical set is 3.
|
|
225044
|
+
annotations: { readOnlyHint: false, openWorldHint: false }
|
|
223729
225045
|
},
|
|
223730
225046
|
{
|
|
223731
225047
|
name: "get_decision_details",
|
|
@@ -224255,9 +225571,9 @@ var require_generate_surface_anchor = __commonJS({
|
|
|
224255
225571
|
var OUT = path.join(__dirname, "..", "src", "generated", "surface-anchor.json");
|
|
224256
225572
|
var ENDPOINT = "https://app.coderifts.com/mcp";
|
|
224257
225573
|
var VOLATILE_KEYS = Object.freeze([]);
|
|
224258
|
-
var SOURCE_REF = "https://raw.githubusercontent.com/coderifts/api-governance/surface-
|
|
224259
|
-
var SOURCE_REF_COMMIT = "
|
|
224260
|
-
var SOURCE_REF_STATUS = `PINNED TO ONE REVISION. source_ref is the wire-format tools[] as served, published in the public coderifts/api-governance repo at tag surface-
|
|
225574
|
+
var SOURCE_REF = "https://raw.githubusercontent.com/coderifts/api-governance/surface-c3ec5f69/tools.wire.v1.json";
|
|
225575
|
+
var SOURCE_REF_COMMIT = "2496038c4bca672e0e9730a8de92db34d0556bb5";
|
|
225576
|
+
var SOURCE_REF_STATUS = `PINNED TO ONE REVISION. source_ref is the wire-format tools[] as served, published in the public coderifts/api-governance repo at tag surface-c3ec5f69 (commit ${SOURCE_REF_COMMIT}). Verified at fill time: the file's own tools_sha256, its tools[] recomputed under the canonical rule in digest_input, and this anchor's tools_sha256 are the same value. HOW TO USE IT: fetch it, recompute the digest yourself, and compare it to tools_sha256 here. IF THEY DIFFER, TRUST NEITHER -- it means the surface moved and this ref was not re-tagged. A tag can be force-moved; the commit SHA above cannot, so pin the SHA URL if you want the stronger form. OUR OBLIGATION: every surface change requires a NEW tag and a NEW source_ref in this file. Skipping that leaves this field pointing at an old surface while still looking authoritative, which is worse than the null it replaced. HOW THE OBLIGATION IS ENFORCED, on both sides: this repo CI-runs generate-surface-anchor.js --check --verify-source-ref, which fetches the ref above, recomputes its digest under the rule in digest_input, and FAILS if it is stale, self-inconsistent, or its tag is gone. The target repo runs scripts/validate-tools-wire.mjs from its own npm test and a CI workflow -- on push, on PR, and daily, because the wire target can go stale without anything in that repo changing. Both SKIP LOUDLY rather than fail on a transport error, and both treat a 404 as a real verdict rather than a network problem. Neither this ref nor those gates is a root of trust: pin the digest at YOUR approval time -- see honesty.pin_at_approval_time.`;
|
|
224261
225577
|
var HONESTY = Object.freeze({
|
|
224262
225578
|
pins_bytes_not_behaviour: "This anchor pins BYTES, not behaviour. It says the tool text you received is the text that was published. It says nothing about whether the model read it, understood it, or obeyed it.",
|
|
224263
225579
|
scoped_to_its_profile: "This digest is scoped to the profile named above and to nothing else. The default-profile digest says NOTHING about the surface served with include_advanced_tools, which is a different tool set with a different digest. A hash without its profile does not identify a surface.",
|
|
@@ -224845,6 +226161,7 @@ var require_decision_result = __commonJS({
|
|
|
224845
226161
|
} = require_policy_pin();
|
|
224846
226162
|
var { sha256hex } = require_chain_attestation();
|
|
224847
226163
|
var { canonicalJson } = require_canonical_json();
|
|
226164
|
+
var { projectNextAgentStep } = require_next_agent_step2();
|
|
224848
226165
|
var {
|
|
224849
226166
|
buildRemediationTransaction,
|
|
224850
226167
|
blockRequiredActionCore
|
|
@@ -224885,6 +226202,41 @@ var require_decision_result = __commonJS({
|
|
|
224885
226202
|
function envelopeSafeForAgent(decision) {
|
|
224886
226203
|
return decision === "ALLOW" || decision === "WARN";
|
|
224887
226204
|
}
|
|
226205
|
+
var SAFE_FOR_AGENT_SEMANTICS = Object.freeze({
|
|
226206
|
+
"decision_result.safe_for_agent": Object.freeze({
|
|
226207
|
+
question: "is the verdict ALLOW/WARN?",
|
|
226208
|
+
kind: "verdict",
|
|
226209
|
+
forced_false_by: Object.freeze([])
|
|
226210
|
+
}),
|
|
226211
|
+
safe_for_agent: Object.freeze({
|
|
226212
|
+
question: "is it actually safe to proceed?",
|
|
226213
|
+
kind: "defense_in_depth",
|
|
226214
|
+
note: "1227: the most-read (flat) field is now defense-in-depth, same as control_envelope. A naive agent reading it must not proceed on a coverage-gapped ALLOW. The raw verdict stays on decision_result \u2014 no information lost.",
|
|
226215
|
+
forced_false_by: Object.freeze([
|
|
226216
|
+
"decision BLOCK",
|
|
226217
|
+
"decision REQUIRE_APPROVAL",
|
|
226218
|
+
"degraded",
|
|
226219
|
+
"coverage_gap",
|
|
226220
|
+
"fallback_reason",
|
|
226221
|
+
"coverage_gap rule_id",
|
|
226222
|
+
"webhook_surface_unanalyzed"
|
|
226223
|
+
])
|
|
226224
|
+
}),
|
|
226225
|
+
"control_envelope.safe_for_agent": Object.freeze({
|
|
226226
|
+
question: "is it actually safe to proceed?",
|
|
226227
|
+
kind: "defense_in_depth",
|
|
226228
|
+
note: "the verdict AND the coverage check; this is the field to gate on",
|
|
226229
|
+
forced_false_by: Object.freeze([
|
|
226230
|
+
"degraded",
|
|
226231
|
+
"coverage_gap",
|
|
226232
|
+
"fallback_reason",
|
|
226233
|
+
"coverage_gap rule_id",
|
|
226234
|
+
"webhook_surface_unanalyzed"
|
|
226235
|
+
])
|
|
226236
|
+
}),
|
|
226237
|
+
invariant: "safe_for_agent == control_envelope.safe_for_agent <= decision_result.safe_for_agent",
|
|
226238
|
+
invariant_means: "defense-in-depth only tightens: true may become false, false never becomes true. The flat field equals control_envelope (1227)."
|
|
226239
|
+
});
|
|
224888
226240
|
function mapSeverity(sev) {
|
|
224889
226241
|
const up = String(sev || "").toUpperCase();
|
|
224890
226242
|
return EVIDENCE_SEVERITIES.includes(up) ? up : "MEDIUM";
|
|
@@ -225026,8 +226378,27 @@ var require_decision_result = __commonJS({
|
|
|
225026
226378
|
// RT-P-20 — fingerprint rebind expected bit (SERVER-authored; under body_hash).
|
|
225027
226379
|
// true = gate must rebind; null/absent on legacy = not_expected (wire compat residual).
|
|
225028
226380
|
// Caller cannot set/delete this — author only in change-set issuance path.
|
|
225029
|
-
fingerprint_binding_expected: null
|
|
226381
|
+
fingerprint_binding_expected: null,
|
|
225030
226382
|
// true | false | null (legacy)
|
|
226383
|
+
// I-1288 — the decision's own remediation SUGGESTION, INSIDE the signed envelope.
|
|
226384
|
+
//
|
|
226385
|
+
// WHY IT MOVED IN. The identical projection has always been on the response root, at
|
|
226386
|
+
// control_envelope.next_agent_step. But k8s-admission, gateway-verifier and the guard's
|
|
226387
|
+
// deployGate are handed the ENVELOPE and nothing else: they could verify the decision and
|
|
226388
|
+
// still not say what to do about it without a second network call to the issuer. A field
|
|
226389
|
+
// that only exists next to the envelope is not available to the parties the envelope was
|
|
226390
|
+
// built for. Placed here it is covered by decision_body_hash, so the receipt signs the
|
|
226391
|
+
// suggestion along with the decision that produced it — a tampered next step no longer
|
|
226392
|
+
// verifies.
|
|
226393
|
+
//
|
|
226394
|
+
// STILL NOT PERMISSION. Being signed makes it authentic, not authoritative: agents branch
|
|
226395
|
+
// on execution_action, exactly as before. Null on the allow class (CONTINUE /
|
|
226396
|
+
// CONTINUE_WITH_MONITORING) is the correct value, not an absent measurement.
|
|
226397
|
+
//
|
|
226398
|
+
// ADDITIVE, so spec_version stays decision-result.v1.1 (producer ENVELOPE COMPATIBILITY
|
|
226399
|
+
// rule 5: additive optional fields do not bump the major). control_envelope keeps emitting
|
|
226400
|
+
// its copy from the same pure function — one projection, two placements, never two rules.
|
|
226401
|
+
next_agent_step: null
|
|
225031
226402
|
});
|
|
225032
226403
|
var SOURCE_SLOTS = Object.freeze([
|
|
225033
226404
|
"repository",
|
|
@@ -225193,6 +226564,10 @@ var require_decision_result = __commonJS({
|
|
|
225193
226564
|
if (hasAdditive && decision === "BLOCK" && additive.required_action_core == null) {
|
|
225194
226565
|
additive.required_action_core = blockRequiredActionCore(reasonCode(context, breakingCount));
|
|
225195
226566
|
}
|
|
226567
|
+
if (hasAdditive) {
|
|
226568
|
+
const raForStep = additive.required_action_core != null && typeof additive.required_action_core === "object" ? additive.required_action_core : required_action;
|
|
226569
|
+
additive.next_agent_step = projectNextAgentStep(execution_action, raForStep);
|
|
226570
|
+
}
|
|
225196
226571
|
if (hasAdditive) {
|
|
225197
226572
|
if (remediation_transaction) {
|
|
225198
226573
|
additive.remediation_transaction = remediation_transaction;
|
|
@@ -225251,6 +226626,7 @@ var require_decision_result = __commonJS({
|
|
|
225251
226626
|
module2.exports = {
|
|
225252
226627
|
buildDecisionResultV1,
|
|
225253
226628
|
envelopeSafeForAgent,
|
|
226629
|
+
SAFE_FOR_AGENT_SEMANTICS,
|
|
225254
226630
|
proseToType,
|
|
225255
226631
|
toUtcSeconds,
|
|
225256
226632
|
computeBodyHash,
|
|
@@ -227107,10 +228483,10 @@ var require_gate_pin = __commonJS({
|
|
|
227107
228483
|
"src/generated/gate-pin.json"(exports2, module2) {
|
|
227108
228484
|
module2.exports = {
|
|
227109
228485
|
repo: "coderifts/contract-gate",
|
|
227110
|
-
sha: "
|
|
227111
|
-
tag: "v0.
|
|
228486
|
+
sha: "1fae5d2bb2b52e1e1b745e649eab8834eac45645",
|
|
228487
|
+
tag: "v0.8.0",
|
|
227112
228488
|
resolved_from: "https://github.com/coderifts/contract-gate refs/tags/v0",
|
|
227113
|
-
resolved_at: "2026-
|
|
228489
|
+
resolved_at: "2026-09-02T07:25:19Z",
|
|
227114
228490
|
note: "STRICT template pins this full commit SHA (GitHub: only a full SHA is immutable). v0 is a tag we move on every release, so it is NOT a pin. Re-run scripts/generate-gate-pin.js on each gate release; Dependabot bumps adopters."
|
|
227115
228491
|
};
|
|
227116
228492
|
}
|
|
@@ -228786,13 +230162,13 @@ var require_agent_host_files_embedded = __commonJS({
|
|
|
228786
230162
|
".cursor/hooks.json"
|
|
228787
230163
|
]);
|
|
228788
230164
|
var AGENT_HOST_FILES = Object.freeze({
|
|
228789
|
-
"AGENTS.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts agent rules\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call
|
|
228790
|
-
"CLAUDE.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call
|
|
228791
|
-
".cursor/rules/coderifts.mdc": '---\ndescription: CodeRifts API governance \u2014 when to preflight and how to branch\nglobs:\nalwaysApply: true\n---\n\n<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call
|
|
228792
|
-
".github/copilot-instructions.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts instructions for GitHub Copilot\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call
|
|
228793
|
-
"coderifts-langgraph-policy.js": '// GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js\n// System policy string for a LangGraph (or similar) agent. Content is generated;\n// identical rule sentences to AGENTS.md / other formats.\n\'use strict\';\n\nmodule.exports = "Call `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\\n\\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\\n\\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\\n\\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\\n\\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\\n\\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not \\"proceed with caution\\" without monitoring.\\n\\nDo not call
|
|
228794
|
-
"openai-agent-instructions.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts agent instructions\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call
|
|
228795
|
-
"skills/api-governance/SKILL.md": '---\nname: api-governance\ndescription: Before merging or shipping any API or tool-contract change: preflight the change set, then branch on execution_action.\n---\n\n# CodeRifts API Governance\n\n<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call
|
|
230165
|
+
"AGENTS.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts agent rules\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call `preflight_change_set` for: a documentation-only change (README, guides, comments) with no contract artifact content change; a static readiness score (a different capability, not a change-set decision); or to verify a receipt you already hold (that is `verify_receipt` \u2014 see the companion-tools rule).\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nThe CodeRifts MCP server exposes exactly three tools \u2014 `preflight_change_set`, `verify_receipt`, `get_decision_details`. Do not invent or assume others.\n\nA receipt authorizes ONE operation: a merge receipt does not authorize a deploy. Before a different operation (deploy, publish), call `preflight_change_set` with `context.operation` set to that operation \u2014 reusing a differently-scoped receipt is not permitted and will fail at the gate.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational \u2014 risk only, `may_execute` is always false \u2014 and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n\nIf the host requests an execution grant (opt-in `include_execution_grant`), the grant is bound to operation + target + after-payload (`scope_hash`) and is short-lived \u2014 never reuse it after the after-payload changes.\n\nAn ATOMIC-profile grant carries `state_nonce` and is single-use at the executor \u2014 if the executor has consumed the nonce, re-preflight; do not retry the same grant.\n\nVersions you may meet elsewhere: `cr.exec.v2` is the issued-token version for atomic execution, and `ENFORCING_STRICT_V1` is the versioned spelling of the strict profile. Neither is the default and neither is required by these rules \u2014 see `docs/grant-versions.md`.\n\nWith a proven tenant\u2194repo binding you may request `derivation:"server"` instead of assembling `artifacts[]` yourself (`context.repository` + `context.base` + `context.head` required; caller-supplied artifacts are rejected on that path).\n\nA commit is only proven when an executor attestation verifies (customer-held executor key, `cas_evidence: executor_attested`); otherwise say "authorized, commit not proven".\n',
|
|
230166
|
+
"CLAUDE.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call `preflight_change_set` for: a documentation-only change (README, guides, comments) with no contract artifact content change; a static readiness score (a different capability, not a change-set decision); or to verify a receipt you already hold (that is `verify_receipt` \u2014 see the companion-tools rule).\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nThe CodeRifts MCP server exposes exactly three tools \u2014 `preflight_change_set`, `verify_receipt`, `get_decision_details`. Do not invent or assume others.\n\nA receipt authorizes ONE operation: a merge receipt does not authorize a deploy. Before a different operation (deploy, publish), call `preflight_change_set` with `context.operation` set to that operation \u2014 reusing a differently-scoped receipt is not permitted and will fail at the gate.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational \u2014 risk only, `may_execute` is always false \u2014 and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n\nIf the host requests an execution grant (opt-in `include_execution_grant`), the grant is bound to operation + target + after-payload (`scope_hash`) and is short-lived \u2014 never reuse it after the after-payload changes.\n\nAn ATOMIC-profile grant carries `state_nonce` and is single-use at the executor \u2014 if the executor has consumed the nonce, re-preflight; do not retry the same grant.\n\nVersions you may meet elsewhere: `cr.exec.v2` is the issued-token version for atomic execution, and `ENFORCING_STRICT_V1` is the versioned spelling of the strict profile. Neither is the default and neither is required by these rules \u2014 see `docs/grant-versions.md`.\n\nWith a proven tenant\u2194repo binding you may request `derivation:"server"` instead of assembling `artifacts[]` yourself (`context.repository` + `context.base` + `context.head` required; caller-supplied artifacts are rejected on that path).\n\nA commit is only proven when an executor attestation verifies (customer-held executor key, `cas_evidence: executor_attested`); otherwise say "authorized, commit not proven".\n',
|
|
230167
|
+
".cursor/rules/coderifts.mdc": '---\ndescription: CodeRifts API governance \u2014 when to preflight and how to branch\nglobs:\nalwaysApply: true\n---\n\n<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call `preflight_change_set` for: a documentation-only change (README, guides, comments) with no contract artifact content change; a static readiness score (a different capability, not a change-set decision); or to verify a receipt you already hold (that is `verify_receipt` \u2014 see the companion-tools rule).\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nThe CodeRifts MCP server exposes exactly three tools \u2014 `preflight_change_set`, `verify_receipt`, `get_decision_details`. Do not invent or assume others.\n\nA receipt authorizes ONE operation: a merge receipt does not authorize a deploy. Before a different operation (deploy, publish), call `preflight_change_set` with `context.operation` set to that operation \u2014 reusing a differently-scoped receipt is not permitted and will fail at the gate.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational \u2014 risk only, `may_execute` is always false \u2014 and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n\nIf the host requests an execution grant (opt-in `include_execution_grant`), the grant is bound to operation + target + after-payload (`scope_hash`) and is short-lived \u2014 never reuse it after the after-payload changes.\n\nAn ATOMIC-profile grant carries `state_nonce` and is single-use at the executor \u2014 if the executor has consumed the nonce, re-preflight; do not retry the same grant.\n\nVersions you may meet elsewhere: `cr.exec.v2` is the issued-token version for atomic execution, and `ENFORCING_STRICT_V1` is the versioned spelling of the strict profile. Neither is the default and neither is required by these rules \u2014 see `docs/grant-versions.md`.\n\nWith a proven tenant\u2194repo binding you may request `derivation:"server"` instead of assembling `artifacts[]` yourself (`context.repository` + `context.base` + `context.head` required; caller-supplied artifacts are rejected on that path).\n\nA commit is only proven when an executor attestation verifies (customer-held executor key, `cas_evidence: executor_attested`); otherwise say "authorized, commit not proven".\n',
|
|
230168
|
+
".github/copilot-instructions.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts instructions for GitHub Copilot\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call `preflight_change_set` for: a documentation-only change (README, guides, comments) with no contract artifact content change; a static readiness score (a different capability, not a change-set decision); or to verify a receipt you already hold (that is `verify_receipt` \u2014 see the companion-tools rule).\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nThe CodeRifts MCP server exposes exactly three tools \u2014 `preflight_change_set`, `verify_receipt`, `get_decision_details`. Do not invent or assume others.\n\nA receipt authorizes ONE operation: a merge receipt does not authorize a deploy. Before a different operation (deploy, publish), call `preflight_change_set` with `context.operation` set to that operation \u2014 reusing a differently-scoped receipt is not permitted and will fail at the gate.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational \u2014 risk only, `may_execute` is always false \u2014 and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n\nIf the host requests an execution grant (opt-in `include_execution_grant`), the grant is bound to operation + target + after-payload (`scope_hash`) and is short-lived \u2014 never reuse it after the after-payload changes.\n\nAn ATOMIC-profile grant carries `state_nonce` and is single-use at the executor \u2014 if the executor has consumed the nonce, re-preflight; do not retry the same grant.\n\nVersions you may meet elsewhere: `cr.exec.v2` is the issued-token version for atomic execution, and `ENFORCING_STRICT_V1` is the versioned spelling of the strict profile. Neither is the default and neither is required by these rules \u2014 see `docs/grant-versions.md`.\n\nWith a proven tenant\u2194repo binding you may request `derivation:"server"` instead of assembling `artifacts[]` yourself (`context.repository` + `context.base` + `context.head` required; caller-supplied artifacts are rejected on that path).\n\nA commit is only proven when an executor attestation verifies (customer-held executor key, `cas_evidence: executor_attested`); otherwise say "authorized, commit not proven".\n',
|
|
230169
|
+
"coderifts-langgraph-policy.js": '// GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js\n// System policy string for a LangGraph (or similar) agent. Content is generated;\n// identical rule sentences to AGENTS.md / other formats.\n\'use strict\';\n\nmodule.exports = "Call `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\\n\\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\\n\\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\\n\\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\\n\\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\\n\\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not \\"proceed with caution\\" without monitoring.\\n\\nDo not call `preflight_change_set` for: a documentation-only change (README, guides, comments) with no contract artifact content change; a static readiness score (a different capability, not a change-set decision); or to verify a receipt you already hold (that is `verify_receipt` \u2014 see the companion-tools rule).\\n\\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\\n\\nThe CodeRifts MCP server exposes exactly three tools \u2014 `preflight_change_set`, `verify_receipt`, `get_decision_details`. Do not invent or assume others.\\n\\nA receipt authorizes ONE operation: a merge receipt does not authorize a deploy. Before a different operation (deploy, publish), call `preflight_change_set` with `context.operation` set to that operation \u2014 reusing a differently-scoped receipt is not permitted and will fail at the gate.\\n\\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\\n\\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\\n\\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\\n\\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational \u2014 risk only, `may_execute` is always false \u2014 and is not permission. Read `execution_action` on the `decision_result` envelope.\\n\\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\\n\\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\\n\\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\\n\\nIf the host requests an execution grant (opt-in `include_execution_grant`), the grant is bound to operation + target + after-payload (`scope_hash`) and is short-lived \u2014 never reuse it after the after-payload changes.\\n\\nAn ATOMIC-profile grant carries `state_nonce` and is single-use at the executor \u2014 if the executor has consumed the nonce, re-preflight; do not retry the same grant.\\n\\nVersions you may meet elsewhere: `cr.exec.v2` is the issued-token version for atomic execution, and `ENFORCING_STRICT_V1` is the versioned spelling of the strict profile. Neither is the default and neither is required by these rules \u2014 see `docs/grant-versions.md`.\\n\\nWith a proven tenant\u2194repo binding you may request `derivation:\\"server\\"` instead of assembling `artifacts[]` yourself (`context.repository` + `context.base` + `context.head` required; caller-supplied artifacts are rejected on that path).\\n\\nA commit is only proven when an executor attestation verifies (customer-held executor key, `cas_evidence: executor_attested`); otherwise say \\"authorized, commit not proven\\".";\n',
|
|
230170
|
+
"openai-agent-instructions.md": '<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\n# CodeRifts agent instructions\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call `preflight_change_set` for: a documentation-only change (README, guides, comments) with no contract artifact content change; a static readiness score (a different capability, not a change-set decision); or to verify a receipt you already hold (that is `verify_receipt` \u2014 see the companion-tools rule).\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nThe CodeRifts MCP server exposes exactly three tools \u2014 `preflight_change_set`, `verify_receipt`, `get_decision_details`. Do not invent or assume others.\n\nA receipt authorizes ONE operation: a merge receipt does not authorize a deploy. Before a different operation (deploy, publish), call `preflight_change_set` with `context.operation` set to that operation \u2014 reusing a differently-scoped receipt is not permitted and will fail at the gate.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational \u2014 risk only, `may_execute` is always false \u2014 and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n\nIf the host requests an execution grant (opt-in `include_execution_grant`), the grant is bound to operation + target + after-payload (`scope_hash`) and is short-lived \u2014 never reuse it after the after-payload changes.\n\nAn ATOMIC-profile grant carries `state_nonce` and is single-use at the executor \u2014 if the executor has consumed the nonce, re-preflight; do not retry the same grant.\n\nVersions you may meet elsewhere: `cr.exec.v2` is the issued-token version for atomic execution, and `ENFORCING_STRICT_V1` is the versioned spelling of the strict profile. Neither is the default and neither is required by these rules \u2014 see `docs/grant-versions.md`.\n\nWith a proven tenant\u2194repo binding you may request `derivation:"server"` instead of assembling `artifacts[]` yourself (`context.repository` + `context.base` + `context.head` required; caller-supplied artifacts are rejected on that path).\n\nA commit is only proven when an executor attestation verifies (customer-held executor key, `cas_evidence: executor_attested`); otherwise say "authorized, commit not proven".\n',
|
|
230171
|
+
"skills/api-governance/SKILL.md": '---\nname: api-governance\ndescription: Before merging or shipping any API or tool-contract change: preflight the change set, then branch on execution_action.\n---\n\n# CodeRifts API Governance\n\n<!-- GENERATED from CodeRifts agent-host-rule (single source). Do not edit rule sentences by hand; run: node scripts/generate-agent-host-files.js -->\n\nCall `preflight_change_set` before merge, deploy, publish, or tool registration when a contract artifact changed (OpenAPI/Swagger, GraphQL, gRPC/protobuf, AsyncAPI, MCP manifest, or agent tool schemas).\n\nSend the complete base-to-head change set: every changed contract artifact with full before and after content. Do not send a single-file subset when other contract files also change.\n\nBranch on `execution_action` only. Do not branch on `decision` and do not branch on `safe_for_agent` (not_for_control_flow_use_execution_action). Canonical `execution_action` values: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP.\n\nAn unrecognised `execution_action` is not permission: fail closed (halt or re-preflight). Well-known code: `not_permission_fail_closed`.\n\nWhen `execution_action` is REQUEST_APPROVAL or STOP, surface the detected patterns and the blast radius, and propose the safer path \u2014 deprecate-then-remove, an additive change, or a new version \u2014 rather than shipping the break.\n\n`CONTINUE_WITH_MONITORING` requires a wired monitoring sink (`monitoringSinkWired`). It is not "proceed with caution" without monitoring.\n\nDo not call `preflight_change_set` for: a documentation-only change (README, guides, comments) with no contract artifact content change; a static readiness score (a different capability, not a change-set decision); or to verify a receipt you already hold (that is `verify_receipt` \u2014 see the companion-tools rule).\n\nIf you already hold a chain receipt and only need authenticity/lifecycle: `verify_receipt`. If you need a past decision by id: `get_decision_details`. Neither replaces preflight for a new change set.\n\nThe CodeRifts MCP server exposes exactly three tools \u2014 `preflight_change_set`, `verify_receipt`, `get_decision_details`. Do not invent or assume others.\n\nA receipt authorizes ONE operation: a merge receipt does not authorize a deploy. Before a different operation (deploy, publish), call `preflight_change_set` with `context.operation` set to that operation \u2014 reusing a differently-scoped receipt is not permitted and will fail at the gate.\n\nA stale or superseded receipt on a changed head requires a NEW preflight \u2014 `verify_receipt` cannot re-diff.\n\nFor mutating tools, put only the guarded version in the agent\'s tool table; keep the raw handler host-only and unreachable from that table. How you name tools is yours \u2014 this is a reachability property, not a product rename of host tools. CodeRifts cannot see or stop a raw call the host makes outside the table it returns; adopt this as a host convention, not as a guarantee from the package.\n\nCodeRifts reports a governance decision and `execution_action`; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.\n\nTo act (mutate a contract, merge, deploy, or publish): call `preflight_change_set` with `preflight_mode` authorize. Analyze is informational \u2014 risk only, `may_execute` is always false \u2014 and is not permission. Read `execution_action` on the `decision_result` envelope.\n\nBefore acting under a held receipt: call `verify_receipt` with the intended `context` (operation, environment, repository, branch, pull_request) for THIS attempt. Do not act on a receipt whose scope does not match.\n\nAct only when `currently_authorized` is true (`control_envelope.receipt_view.currently_authorized`). A valid-looking token is not permission if `currently_authorized` is false or omitted.\n\nCommit / CAS evidence is a separate measurement (`commit_observation` on GuardOutcome). It is not a substitute for authorize + `currently_authorized`. Production hosts that want the fail-closed conjunction lock it with `profile: ENFORCING_STRICT` on withCodeRifts.\n\nIf the host requests an execution grant (opt-in `include_execution_grant`), the grant is bound to operation + target + after-payload (`scope_hash`) and is short-lived \u2014 never reuse it after the after-payload changes.\n\nAn ATOMIC-profile grant carries `state_nonce` and is single-use at the executor \u2014 if the executor has consumed the nonce, re-preflight; do not retry the same grant.\n\nVersions you may meet elsewhere: `cr.exec.v2` is the issued-token version for atomic execution, and `ENFORCING_STRICT_V1` is the versioned spelling of the strict profile. Neither is the default and neither is required by these rules \u2014 see `docs/grant-versions.md`.\n\nWith a proven tenant\u2194repo binding you may request `derivation:"server"` instead of assembling `artifacts[]` yourself (`context.repository` + `context.base` + `context.head` required; caller-supplied artifacts are rejected on that path).\n\nA commit is only proven when an executor attestation verifies (customer-held executor key, `cas_evidence: executor_attested`); otherwise say "authorized, commit not proven".\n',
|
|
228796
230172
|
".claude/settings.json": '{\n "hooks": {\n "PreToolUse": [\n {\n "matcher": "Write|Edit|MultiEdit",\n "hooks": [\n {\n "type": "command",\n "command": "coderifts claude-hook",\n "timeout": 60\n }\n ]\n }\n ]\n }\n}\n',
|
|
228797
230173
|
".cursor/hooks.json": '{\n "version": 1,\n "hooks": {\n "preToolUse": [\n {\n "command": "coderifts cursor-hook",\n "matcher": "Write|Delete",\n "timeout": 60,\n "failClosed": true\n }\n ]\n }\n}\n'
|
|
228798
230174
|
});
|
|
@@ -228958,6 +230334,7 @@ ${USAGE}` };
|
|
|
228958
230334
|
var AGENT_SETUP_HOOK_WIRE_LINES = Object.freeze([
|
|
228959
230335
|
chalk.bold(" Claude Code hook (.claude/settings.json): fail-closed PreToolUse"),
|
|
228960
230336
|
chalk.dim(" matcher Write|Edit|MultiEdit \u2192 coderifts claude-hook (exit 2 = BLOCK)."),
|
|
230337
|
+
chalk.dim(" Path family: OpenAPI/Swagger, GraphQL, *.proto, AsyncAPI, MCP, tool-schema.json (plus git config coderifts.specPath; exclude via coderifts.specPathExclude)."),
|
|
228961
230338
|
chalk.dim(" Missing key / API down / unreadable spec \u2192 exit 2 (enforce_indeterminate), not ALLOW."),
|
|
228962
230339
|
chalk.dim(" Opt-out: CODERIFTS_ADVISORY=1|true restores soft-allow when governance could not run."),
|
|
228963
230340
|
chalk.dim(" CODERIFTS_STRICT=1 cannot be weakened by ADVISORY.")
|
|
@@ -229358,6 +230735,7 @@ exit 0
|
|
|
229358
230735
|
say(`Claude Code PreToolUse hook written to ${dest}`);
|
|
229359
230736
|
if (backedUp) say(`Backup: ${backedUp}`);
|
|
229360
230737
|
say("matcher Write|Edit|MultiEdit \u2192 coderifts claude-hook (exit 2 = BLOCK).");
|
|
230738
|
+
say("governs the contract path family (OpenAPI/Swagger, GraphQL, *.proto, AsyncAPI, MCP, tool-schema) plus git config coderifts.specPath; opt out one path with coderifts.specPathExclude.");
|
|
229361
230739
|
return { exitCode: 0, code: "OK", path: dest, backedUp, wrote: true };
|
|
229362
230740
|
}
|
|
229363
230741
|
var CURSOR_HOOK_BIN = "coderifts cursor-hook";
|
|
@@ -256034,10 +257412,12 @@ var require_github_workflow_pin = __commonJS({
|
|
|
256034
257412
|
"use strict";
|
|
256035
257413
|
var { STATUS } = require_github_enforcement();
|
|
256036
257414
|
var PIN_REASON = Object.freeze({
|
|
256037
|
-
/** The pinned sha is the
|
|
257415
|
+
/** The pinned sha is the head commit sha being merged — GitHub's field, grants PASS. */
|
|
256038
257416
|
WORKFLOW_SHA_MATCHES_HEAD: "workflow_sha_matches_head",
|
|
256039
257417
|
/** A pin exists, but it names bytes that are not what is at the head. */
|
|
256040
257418
|
WORKFLOW_SHA_STALE: "workflow_sha_stale",
|
|
257419
|
+
/** Pin equals the file blob SHA, not a commit. Named; does NOT grant PASS. */
|
|
257420
|
+
WORKFLOW_SHA_IS_BLOB: "workflow_sha_is_blob",
|
|
256041
257421
|
/** No sha in the rule — the ruleset names a path, so rewriting the file changes what runs. */
|
|
256042
257422
|
WORKFLOW_NOT_PINNED: "workflow_not_pinned",
|
|
256043
257423
|
/** We could not read the workflow file at the head, so no comparison is possible. */
|
|
@@ -256053,7 +257433,8 @@ var require_github_workflow_pin = __commonJS({
|
|
|
256053
257433
|
workflow_ref: null,
|
|
256054
257434
|
workflow_sha: null,
|
|
256055
257435
|
workflow_sha_matches_head: false,
|
|
256056
|
-
matched_against: null
|
|
257436
|
+
matched_against: null,
|
|
257437
|
+
grants_pass: false
|
|
256057
257438
|
};
|
|
256058
257439
|
if (!pin || !Array.isArray(pin.workflows) || pin.workflows.length === 0) {
|
|
256059
257440
|
return {
|
|
@@ -256091,14 +257472,26 @@ var require_github_workflow_pin = __commonJS({
|
|
|
256091
257472
|
}
|
|
256092
257473
|
const matchedBlob = sameSha(pinned.sha, blobSha);
|
|
256093
257474
|
const matchedCommit = sameSha(pinned.sha, headCommitSha);
|
|
256094
|
-
if (
|
|
257475
|
+
if (matchedCommit) {
|
|
256095
257476
|
return {
|
|
256096
257477
|
...fields,
|
|
256097
257478
|
status: STATUS.VERIFIED,
|
|
256098
257479
|
reason_code: PIN_REASON.WORKFLOW_SHA_MATCHES_HEAD,
|
|
256099
257480
|
workflow_sha_matches_head: true,
|
|
256100
|
-
matched_against:
|
|
256101
|
-
|
|
257481
|
+
matched_against: "commit",
|
|
257482
|
+
grants_pass: true,
|
|
257483
|
+
reason: `the ruleset pins ${fields.workflow_path} to ${fields.workflow_sha}, which is the head commit being merged (GitHub workflows[].sha is a commit SHA, not a file blob). That match grants PASS. Moving this pin requires editing the ruleset (repository administration), a different permission from workflow write \u2014 so the check is attributable to THIS workflow, not merely to Actions. It still does not establish that the pinned workflow ran, nor that bypass actors cannot skip the ruleset entirely, nor that the pin equals the file blob SHA.`
|
|
257484
|
+
};
|
|
257485
|
+
}
|
|
257486
|
+
if (matchedBlob) {
|
|
257487
|
+
return {
|
|
257488
|
+
...fields,
|
|
257489
|
+
status: STATUS.UNVERIFIABLE,
|
|
257490
|
+
reason_code: PIN_REASON.WORKFLOW_SHA_IS_BLOB,
|
|
257491
|
+
workflow_sha_matches_head: false,
|
|
257492
|
+
matched_against: "blob",
|
|
257493
|
+
grants_pass: false,
|
|
257494
|
+
reason: "pinned sha matches the file blob, not a commit \u2014 GitHub treats workflows[].sha as a commit SHA. Blob equality is named and does not grant PASS."
|
|
256102
257495
|
};
|
|
256103
257496
|
}
|
|
256104
257497
|
return {
|
|
@@ -256107,9 +257500,26 @@ var require_github_workflow_pin = __commonJS({
|
|
|
256107
257500
|
reason_code: PIN_REASON.WORKFLOW_SHA_STALE,
|
|
256108
257501
|
workflow_sha_matches_head: false,
|
|
256109
257502
|
matched_against: null,
|
|
257503
|
+
grants_pass: false,
|
|
256110
257504
|
reason: `the ruleset pins ${fields.workflow_path} to ${fields.workflow_sha}, but the head carries ${blobSha || headCommitSha || "(nothing readable)"}. A pin to bytes nobody is merging gates nothing.`
|
|
256111
257505
|
};
|
|
256112
257506
|
}
|
|
257507
|
+
function evidenceStatement(headComparison) {
|
|
257508
|
+
if (headComparison && headComparison.grants_pass === true) {
|
|
257509
|
+
return "With the required workflow pinned by sha and that sha matching the head commit SHA (GitHub workflows[].sha is a commit SHA, not a file blob), the check is attributable to this workflow rather than to GitHub Actions in general: moving the pin requires repository administration, which is a different permission from workflow write. The common-issuer objection is closed WITHOUT a second GitHub App. This is not a blob-sha content pin.";
|
|
257510
|
+
}
|
|
257511
|
+
if (headComparison && headComparison.matched_against === "blob") {
|
|
257512
|
+
return "The pinned sha equals the workflow file blob, not the head commit. GitHub treats workflows[].sha as a commit SHA, so blob equality does not grant PASS. The common-issuer objection is not closed by a blob match.";
|
|
257513
|
+
}
|
|
257514
|
+
const code = headComparison && headComparison.reason_code;
|
|
257515
|
+
if (code === PIN_REASON.WORKFLOW_SHA_STALE) {
|
|
257516
|
+
return "A sha-pinned required workflow exists, but the pin names bytes that are not on the head. A stale pin gates nothing and does not grant PASS.";
|
|
257517
|
+
}
|
|
257518
|
+
if (code === PIN_REASON.WORKFLOW_FILE_UNREADABLE) {
|
|
257519
|
+
return "A sha-pinned required workflow exists, but the pin could not be compared with the head. That is UNVERIFIABLE, not a match, and does not grant PASS.";
|
|
257520
|
+
}
|
|
257521
|
+
return "Without a sha-pinned required workflow, the issuer proves the check came from GitHub Actions, not that it came from this workflow. Anyone who can write .github/workflows can post a passing check under the same shared issuer id.";
|
|
257522
|
+
}
|
|
256113
257523
|
function workflowBindingEvidence(pin, headComparison) {
|
|
256114
257524
|
return {
|
|
256115
257525
|
pin_status: pin ? pin.status : STATUS.UNVERIFIABLE,
|
|
@@ -256119,10 +257529,11 @@ var require_github_workflow_pin = __commonJS({
|
|
|
256119
257529
|
workflow_sha: headComparison.workflow_sha,
|
|
256120
257530
|
workflow_sha_matches_head: headComparison.workflow_sha_matches_head,
|
|
256121
257531
|
matched_against: headComparison.matched_against,
|
|
257532
|
+
grants_pass: headComparison.grants_pass === true,
|
|
256122
257533
|
status: headComparison.status,
|
|
256123
257534
|
reason_code: headComparison.reason_code,
|
|
256124
257535
|
reason: headComparison.reason,
|
|
256125
|
-
statement: headComparison
|
|
257536
|
+
statement: evidenceStatement(headComparison)
|
|
256126
257537
|
};
|
|
256127
257538
|
}
|
|
256128
257539
|
module2.exports = { PIN_REASON, evaluateWorkflowShaMatchesHead, workflowBindingEvidence };
|
|
@@ -256645,12 +258056,27 @@ var require_setup_required_check = __commonJS({
|
|
|
256645
258056
|
}
|
|
256646
258057
|
const commitRead = runApi([`repos/${owner}/${repo}/commits/${encodeURIComponent(branch)}`], { cwd });
|
|
256647
258058
|
const commitSha = commitRead && commitRead.ok && commitRead.body && (typeof commitRead.body.sha === "string" ? commitRead.body.sha : commitRead.body.commit && commitRead.body.commit.sha) || null;
|
|
258059
|
+
if (!commitSha || !/^[0-9a-f]{40}$/i.test(commitSha)) {
|
|
258060
|
+
if (!options.json) {
|
|
258061
|
+
logErr(chalk.red(`Could not resolve a commit SHA for ${branch}.`));
|
|
258062
|
+
logErr(" GitHub ruleset workflows[].sha is a commit SHA, not a file blob SHA \u2014 refusing to pin.");
|
|
258063
|
+
}
|
|
258064
|
+
return finish(EXIT.ERROR, {
|
|
258065
|
+
ok: false,
|
|
258066
|
+
code: "WORKFLOW_COMMIT_SHA_UNRESOLVED",
|
|
258067
|
+
owner,
|
|
258068
|
+
repo,
|
|
258069
|
+
branch,
|
|
258070
|
+
workflow_path: WORKFLOW_REL,
|
|
258071
|
+
http_status: commitRead ? commitRead.status : null
|
|
258072
|
+
});
|
|
258073
|
+
}
|
|
256648
258074
|
const rulesetDocs = fetchRulesetDocs(runApi, owner, repo, cwd) || [];
|
|
256649
258075
|
const existing = findExistingWorkflowRuleset(rulesetDocs, WORKFLOW_REL);
|
|
256650
258076
|
const created = buildWorkflowRulesetPayload({
|
|
256651
258077
|
repositoryId,
|
|
256652
258078
|
branch,
|
|
256653
|
-
sha:
|
|
258079
|
+
sha: commitSha,
|
|
256654
258080
|
path: WORKFLOW_REL
|
|
256655
258081
|
});
|
|
256656
258082
|
const payload = existing ? mergeWorkflowRule(existing, created) : created;
|
|
@@ -256661,7 +258087,8 @@ var require_setup_required_check = __commonJS({
|
|
|
256661
258087
|
if (!options.json) {
|
|
256662
258088
|
log(chalk.yellow(`Dry-run: pin ${WORKFLOW_REL} as a required workflow on ${branch}.`));
|
|
256663
258089
|
log(` repo: ${owner}/${repo} (id ${repositoryId})`);
|
|
256664
|
-
log(`
|
|
258090
|
+
log(` commit: ${commitSha}`);
|
|
258091
|
+
log(` blob (file object): ${blobSha}`);
|
|
256665
258092
|
log(` ${existing ? `update ruleset ${existing.id}` : "create ruleset"} ${payload.name}`);
|
|
256666
258093
|
log("");
|
|
256667
258094
|
log(cmdText);
|
|
@@ -257463,9 +258890,22 @@ var require_enforce_check = __commonJS({
|
|
|
257463
258890
|
);
|
|
257464
258891
|
}
|
|
257465
258892
|
}
|
|
258893
|
+
const requireBinding = options.requireWorkflowBinding === true;
|
|
258894
|
+
const bindingGrantsPass = report.workflow_binding && report.workflow_binding.grants_pass === true;
|
|
258895
|
+
const bindingExit = requireBinding && !bindingGrantsPass ? 1 : 0;
|
|
258896
|
+
if (bindingExit !== 0) {
|
|
258897
|
+
const wb = report.workflow_binding || {};
|
|
258898
|
+
errLog(chalk.red(
|
|
258899
|
+
`--require-workflow-binding: the required workflow is not sha-pinned to this head (status ${wb.status || "UNKNOWN"}${wb.reason_code ? `, ${wb.reason_code}` : ""}).`
|
|
258900
|
+
));
|
|
258901
|
+
if (wb.reason) errLog(chalk.dim(` ${wb.reason}`));
|
|
258902
|
+
errLog(chalk.dim(
|
|
258903
|
+
" This is the CLI audit verdict on the Action path, not a merge block \u2014 the App-path clamp is a separate control."
|
|
258904
|
+
));
|
|
258905
|
+
}
|
|
257466
258906
|
if (options.json) log(JSON.stringify(report, null, 2));
|
|
257467
258907
|
else log(renderHuman(report));
|
|
257468
|
-
return { exitCode:
|
|
258908
|
+
return { exitCode: bindingExit, report };
|
|
257469
258909
|
}
|
|
257470
258910
|
module2.exports = {
|
|
257471
258911
|
runEnforceCheck,
|
|
@@ -257558,7 +258998,7 @@ var require_enforce = __commonJS({
|
|
|
257558
258998
|
return { exitCode: 1, error: "check_apply_conflict", outcomes: [] };
|
|
257559
258999
|
}
|
|
257560
259000
|
const { runEnforceCheck } = require_enforce_check();
|
|
257561
|
-
return runEnforceCheck(options, deps);
|
|
259001
|
+
return runEnforceCheck({ ...options, requireWorkflowBinding: options.requireWorkflowBinding === true }, deps);
|
|
257562
259002
|
}
|
|
257563
259003
|
const apply = options.apply === true;
|
|
257564
259004
|
const getKey = deps.getApiKey || getApiKey;
|