@coderifts/agent-guard 3.0.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -1
- package/dist/cjs/artifact-resolver.d.ts +8 -0
- package/dist/cjs/artifact-resolver.d.ts.map +1 -1
- package/dist/cjs/artifact-resolver.js +12 -1
- package/dist/cjs/artifact-resolver.js.map +1 -1
- package/dist/cjs/conditional-write.d.ts +92 -0
- package/dist/cjs/conditional-write.d.ts.map +1 -0
- package/dist/cjs/conditional-write.js +96 -0
- package/dist/cjs/conditional-write.js.map +1 -0
- package/dist/cjs/deploy-bind.d.ts +123 -0
- package/dist/cjs/deploy-bind.d.ts.map +1 -0
- package/dist/cjs/deploy-bind.js +112 -0
- package/dist/cjs/deploy-bind.js.map +1 -0
- package/dist/cjs/enforcement-gate.d.ts +13 -4
- package/dist/cjs/enforcement-gate.d.ts.map +1 -1
- package/dist/cjs/enforcement-gate.js +32 -7
- package/dist/cjs/enforcement-gate.js.map +1 -1
- package/dist/cjs/execution-proof.d.ts +145 -0
- package/dist/cjs/execution-proof.d.ts.map +1 -0
- package/dist/cjs/execution-proof.js +168 -0
- package/dist/cjs/execution-proof.js.map +1 -0
- package/dist/cjs/freshness.d.ts +244 -0
- package/dist/cjs/freshness.d.ts.map +1 -0
- package/dist/cjs/freshness.js +395 -0
- package/dist/cjs/freshness.js.map +1 -0
- package/dist/cjs/guard.d.ts +8 -1
- package/dist/cjs/guard.d.ts.map +1 -1
- package/dist/cjs/guard.js +181 -38
- package/dist/cjs/guard.js.map +1 -1
- package/dist/cjs/index.d.ts +12 -4
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +34 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/read-decision.d.ts +47 -0
- package/dist/cjs/read-decision.d.ts.map +1 -0
- package/dist/cjs/read-decision.js +161 -0
- package/dist/cjs/read-decision.js.map +1 -0
- package/dist/cjs/tool-registry.d.ts.map +1 -1
- package/dist/cjs/tool-registry.js +12 -1
- package/dist/cjs/tool-registry.js.map +1 -1
- package/dist/cjs/types.d.ts +47 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/with-coderifts.d.ts +76 -8
- package/dist/cjs/with-coderifts.d.ts.map +1 -1
- package/dist/cjs/with-coderifts.js +185 -14
- package/dist/cjs/with-coderifts.js.map +1 -1
- package/dist/esm/artifact-resolver.d.ts +8 -0
- package/dist/esm/artifact-resolver.d.ts.map +1 -1
- package/dist/esm/artifact-resolver.js +11 -1
- package/dist/esm/artifact-resolver.js.map +1 -1
- package/dist/esm/conditional-write.d.ts +92 -0
- package/dist/esm/conditional-write.d.ts.map +1 -0
- package/dist/esm/conditional-write.js +91 -0
- package/dist/esm/conditional-write.js.map +1 -0
- package/dist/esm/deploy-bind.d.ts +123 -0
- package/dist/esm/deploy-bind.d.ts.map +1 -0
- package/dist/esm/deploy-bind.js +108 -0
- package/dist/esm/deploy-bind.js.map +1 -0
- package/dist/esm/enforcement-gate.d.ts +13 -4
- package/dist/esm/enforcement-gate.d.ts.map +1 -1
- package/dist/esm/enforcement-gate.js +32 -7
- package/dist/esm/enforcement-gate.js.map +1 -1
- package/dist/esm/execution-proof.d.ts +145 -0
- package/dist/esm/execution-proof.d.ts.map +1 -0
- package/dist/esm/execution-proof.js +162 -0
- package/dist/esm/execution-proof.js.map +1 -0
- package/dist/esm/freshness.d.ts +244 -0
- package/dist/esm/freshness.d.ts.map +1 -0
- package/dist/esm/freshness.js +384 -0
- package/dist/esm/freshness.js.map +1 -0
- package/dist/esm/guard.d.ts +8 -1
- package/dist/esm/guard.d.ts.map +1 -1
- package/dist/esm/guard.js +180 -37
- package/dist/esm/guard.js.map +1 -1
- package/dist/esm/index.d.ts +12 -4
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +12 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/read-decision.d.ts +47 -0
- package/dist/esm/read-decision.d.ts.map +1 -0
- package/dist/esm/read-decision.js +153 -0
- package/dist/esm/read-decision.js.map +1 -0
- package/dist/esm/tool-registry.d.ts.map +1 -1
- package/dist/esm/tool-registry.js +12 -1
- package/dist/esm/tool-registry.js.map +1 -1
- package/dist/esm/types.d.ts +47 -1
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/with-coderifts.d.ts +76 -8
- package/dist/esm/with-coderifts.d.ts.map +1 -1
- package/dist/esm/with-coderifts.js +185 -14
- package/dist/esm/with-coderifts.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* bindDeploy — pure deploy-TIME composition over deployGate (#8).
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: deployGate is the pure decision; nothing in this package used to
|
|
6
|
+
* invoke it at the moment of deploying. The merge gate has the same shape
|
|
7
|
+
* (gateDecision is pure; GitHub enforces via required checks the package does not
|
|
8
|
+
* control). Deploy generalises that pattern with two differences:
|
|
9
|
+
* 1. There is no pull request / required status check to hang on — the host must
|
|
10
|
+
* call this from the CD step itself.
|
|
11
|
+
* 2. The environment name is a HOST ASSERTION. The receipt's bound_environment is
|
|
12
|
+
* signed evidence; the deploy target's environment string is not verified by us.
|
|
13
|
+
* A host can claim "staging" while deploying to production. The output says so.
|
|
14
|
+
*
|
|
15
|
+
* This module performs NO I/O, does NOT re-verify receipts, and does NOT act on a
|
|
16
|
+
* pipeline. pipeline_action is always 'not_observed'. inescapable_deploy still comes
|
|
17
|
+
* only from deployGate (ENFORCING ∧ ¬bypass) — never flipped here.
|
|
18
|
+
*
|
|
19
|
+
* External note: coderifts-app CLI `deploy-gate` historically inlined a similar bind
|
|
20
|
+
* (deployBind). That is a consumer; this is the package-local pure entry hosts should
|
|
21
|
+
* call so the decision logic has a first-class caller in-repo.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.DEPLOY_REPAIRABLE_REASONS = void 0;
|
|
25
|
+
exports.bindDeploy = bindDeploy;
|
|
26
|
+
const deploy_gate_js_1 = require("./deploy-gate.js");
|
|
27
|
+
/** Reasons a fresh re-preflight for this { env, artifact } can repair. */
|
|
28
|
+
const REPAIRABLE = new Set([
|
|
29
|
+
'env_mismatch',
|
|
30
|
+
'stale_artifact',
|
|
31
|
+
'operation_mismatch',
|
|
32
|
+
'receipt_not_authorized',
|
|
33
|
+
'fingerprint_mismatch',
|
|
34
|
+
'body_hash_mismatch',
|
|
35
|
+
'no_receipt',
|
|
36
|
+
'inputs_incomplete',
|
|
37
|
+
]);
|
|
38
|
+
exports.DEPLOY_REPAIRABLE_REASONS = REPAIRABLE;
|
|
39
|
+
function asHostAssertedEnvironment(env) {
|
|
40
|
+
if (typeof env === 'string') {
|
|
41
|
+
return { name: env, provenance: 'host_asserted' };
|
|
42
|
+
}
|
|
43
|
+
const name = env && typeof env.name === 'string' ? env.name : '';
|
|
44
|
+
// Force provenance — a host cannot pass provenance: 'verified' through this API.
|
|
45
|
+
return { name, provenance: 'host_asserted' };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Pure deploy-time entry: bind host claims + finished receipt view into deployGate.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* const r = bindDeploy({
|
|
53
|
+
* environment: { name: 'production', provenance: 'host_asserted' },
|
|
54
|
+
* artifact_id: digest,
|
|
55
|
+
* receipt: receiptView,
|
|
56
|
+
* pipeline_enforcement: { enforcement: 'ENFORCING', bypass_possible: false },
|
|
57
|
+
* });
|
|
58
|
+
* // r.decision_allows_deploy — decision only
|
|
59
|
+
* // r.pipeline_action === 'not_observed' — we did not enforce
|
|
60
|
+
* // r.environment.provenance === 'host_asserted' — we did not verify the target name
|
|
61
|
+
* if (!r.decision_allows_deploy) process.exit(1); // host pipeline chooses to honour
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
function bindDeploy(input) {
|
|
65
|
+
const environment = asHostAssertedEnvironment(input.environment);
|
|
66
|
+
const artifact_id = input.artifact_id == null ? '' : String(input.artifact_id);
|
|
67
|
+
const operation = input.operation ?? 'deploy';
|
|
68
|
+
const deployTarget = {
|
|
69
|
+
environment: environment.name,
|
|
70
|
+
artifact_id,
|
|
71
|
+
...(input.service != null ? { service: input.service } : {}),
|
|
72
|
+
...(input.pipeline_run_id != null ? { pipeline_run_id: input.pipeline_run_id } : {}),
|
|
73
|
+
};
|
|
74
|
+
const requiredContext = {
|
|
75
|
+
operation,
|
|
76
|
+
enforcement: input.pipeline_enforcement || { enforcement: 'UNKNOWN', bypass_possible: true },
|
|
77
|
+
...(input.service != null ? { service: input.service } : {}),
|
|
78
|
+
...(input.expected_fingerprint != null
|
|
79
|
+
? { expected_fingerprint: input.expected_fingerprint }
|
|
80
|
+
: {}),
|
|
81
|
+
...(input.expected_body_hash != null
|
|
82
|
+
? { expected_body_hash: input.expected_body_hash }
|
|
83
|
+
: {}),
|
|
84
|
+
...(input.allowPending != null ? { allowPending: input.allowPending } : {}),
|
|
85
|
+
...(input.allowWarnDeploy != null ? { allowWarnDeploy: input.allowWarnDeploy } : {}),
|
|
86
|
+
...(input.allowPrefixCompare != null
|
|
87
|
+
? { allowPrefixCompare: input.allowPrefixCompare }
|
|
88
|
+
: {}),
|
|
89
|
+
};
|
|
90
|
+
const gate = (0, deploy_gate_js_1.deployGate)({
|
|
91
|
+
deployTarget,
|
|
92
|
+
receipt: input.receipt,
|
|
93
|
+
requiredContext,
|
|
94
|
+
...(input.allowPending != null ? { allowPending: input.allowPending } : {}),
|
|
95
|
+
...(input.allowWarnDeploy != null ? { allowWarnDeploy: input.allowWarnDeploy } : {}),
|
|
96
|
+
...(input.allowPrefixCompare != null
|
|
97
|
+
? { allowPrefixCompare: input.allowPrefixCompare }
|
|
98
|
+
: {}),
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
gate,
|
|
102
|
+
decision_allows_deploy: gate.deploy_allowed === true,
|
|
103
|
+
deploy_check_status: gate.state,
|
|
104
|
+
reason: gate.reason,
|
|
105
|
+
must_re_preflight: REPAIRABLE.has(gate.reason),
|
|
106
|
+
environment, // always provenance: 'host_asserted'
|
|
107
|
+
artifact_id,
|
|
108
|
+
pipeline_action: 'not_observed',
|
|
109
|
+
inescapable_deploy: gate.inescapable_deploy === true,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=deploy-bind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-bind.js","sourceRoot":"","sources":["../../src/deploy-bind.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Client-side authorization gate (P0-b/c) — mirrors the server §106 (binding), §111 (fail-closed on
|
|
3
|
-
* degraded) and §115 (safe_for_agent) in the guard
|
|
4
|
-
*
|
|
3
|
+
* degraded) and §115 (safe_for_agent) in the guard. All checks are LOCAL and fail-closed.
|
|
4
|
+
*
|
|
5
|
+
* Threat model (bounded): a raw execution_action is not trusted alone when the response has NO
|
|
6
|
+
* receipt — without a signed decision_body_hash, a proxy or intermediary can flip fields. When a
|
|
7
|
+
* receipt IS present, decision_body_hash covers the RFC 8785-canonical envelope (minus receipt and
|
|
8
|
+
* the hash field itself) and the receipt signature covers that hash, so execution_action cannot be
|
|
9
|
+
* flipped without the recomputed hash diverging or a forged signature. The gate still reconciles
|
|
10
|
+
* decision↔action locally (stricter wins), fails closed on a PRESENT-but-unrecognised action
|
|
11
|
+
* (version skew — not a missing-action fallback), and never treats an unknown value as permission.
|
|
5
12
|
*
|
|
6
13
|
* Composes with the P0-a receipt binding (receipt-binding.ts). This module reconciles the DECISION
|
|
7
14
|
* itself; receipt-binding authenticates the envelope the decision rides on.
|
|
@@ -25,6 +32,8 @@ export type GateResult = {
|
|
|
25
32
|
};
|
|
26
33
|
/**
|
|
27
34
|
* Reconcile an envelope's decision fail-closed. Order:
|
|
35
|
+
* 0. execution_action PRESENT but not in closed set → EXECUTION_ACTION_UNRECOGNISED
|
|
36
|
+
* (version skew; distinct from DECISION_INCONSISTENT — reconciliation is impossible)
|
|
28
37
|
* 1. decision present + valid enum (CE-EP-04) → DECISION_INCONSISTENT
|
|
29
38
|
* 2. effective decision = STRICTEST(envelope.decision, action-implied, top-level decision/action)
|
|
30
39
|
* (CE-EP-01, CE-CC-01) — BLOCK/REQUIRE_APPROVAL → clean block (positive control CE-EP-02 kept)
|
|
@@ -34,9 +43,9 @@ export type GateResult = {
|
|
|
34
43
|
*
|
|
35
44
|
* @param response the raw preflight response (for the top-level decision/action, CE-CC-01)
|
|
36
45
|
* @param envelope the decision_result envelope
|
|
37
|
-
* @param executionAction rd.executionAction from readDecision
|
|
46
|
+
* @param executionAction rd.executionAction from readDecision (closed Action, or raw string if unrecognised)
|
|
38
47
|
* @param sentArtifacts the artifacts the guard sent to preflight (for the digest bind)
|
|
39
48
|
*/
|
|
40
|
-
export declare function evaluateEnvelope(response: unknown, envelope: Record<string, unknown>, executionAction: Action, sentArtifacts: Artifact[]): GateResult;
|
|
49
|
+
export declare function evaluateEnvelope(response: unknown, envelope: Record<string, unknown>, executionAction: Action | string, sentArtifacts: Artifact[]): GateResult;
|
|
41
50
|
export {};
|
|
42
51
|
//# sourceMappingURL=enforcement-gate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforcement-gate.d.ts","sourceRoot":"","sources":["../../src/enforcement-gate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"enforcement-gate.d.ts","sourceRoot":"","sources":["../../src/enforcement-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3D,KAAK,MAAM,GAAG,UAAU,GAAG,0BAA0B,GAAG,kBAAkB,GAAG,MAAM,CAAC;AAoBpF,wGAAwG;AACxG,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAMnE;AAED,6FAA6F;AAC7F,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAKtE;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,GAC/C;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,OAAO,GAAG,kBAAkB,CAAA;CAAE,GACnE;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,cAAc,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,eAAe,EAAE,MAAM,GAAG,MAAM,EAChC,aAAa,EAAE,QAAQ,EAAE,GACxB,UAAU,CAoEZ"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Client-side authorization gate (P0-b/c) — mirrors the server §106 (binding), §111 (fail-closed on
|
|
4
|
-
* degraded) and §115 (safe_for_agent) in the guard
|
|
5
|
-
*
|
|
4
|
+
* degraded) and §115 (safe_for_agent) in the guard. All checks are LOCAL and fail-closed.
|
|
5
|
+
*
|
|
6
|
+
* Threat model (bounded): a raw execution_action is not trusted alone when the response has NO
|
|
7
|
+
* receipt — without a signed decision_body_hash, a proxy or intermediary can flip fields. When a
|
|
8
|
+
* receipt IS present, decision_body_hash covers the RFC 8785-canonical envelope (minus receipt and
|
|
9
|
+
* the hash field itself) and the receipt signature covers that hash, so execution_action cannot be
|
|
10
|
+
* flipped without the recomputed hash diverging or a forged signature. The gate still reconciles
|
|
11
|
+
* decision↔action locally (stricter wins), fails closed on a PRESENT-but-unrecognised action
|
|
12
|
+
* (version skew — not a missing-action fallback), and never treats an unknown value as permission.
|
|
6
13
|
*
|
|
7
14
|
* Composes with the P0-a receipt binding (receipt-binding.ts). This module reconciles the DECISION
|
|
8
15
|
* itself; receipt-binding authenticates the envelope the decision rides on.
|
|
@@ -45,6 +52,8 @@ function computeBundleFingerprint(artifacts) {
|
|
|
45
52
|
}
|
|
46
53
|
/**
|
|
47
54
|
* Reconcile an envelope's decision fail-closed. Order:
|
|
55
|
+
* 0. execution_action PRESENT but not in closed set → EXECUTION_ACTION_UNRECOGNISED
|
|
56
|
+
* (version skew; distinct from DECISION_INCONSISTENT — reconciliation is impossible)
|
|
48
57
|
* 1. decision present + valid enum (CE-EP-04) → DECISION_INCONSISTENT
|
|
49
58
|
* 2. effective decision = STRICTEST(envelope.decision, action-implied, top-level decision/action)
|
|
50
59
|
* (CE-EP-01, CE-CC-01) — BLOCK/REQUIRE_APPROVAL → clean block (positive control CE-EP-02 kept)
|
|
@@ -54,18 +63,34 @@ function computeBundleFingerprint(artifacts) {
|
|
|
54
63
|
*
|
|
55
64
|
* @param response the raw preflight response (for the top-level decision/action, CE-CC-01)
|
|
56
65
|
* @param envelope the decision_result envelope
|
|
57
|
-
* @param executionAction rd.executionAction from readDecision
|
|
66
|
+
* @param executionAction rd.executionAction from readDecision (closed Action, or raw string if unrecognised)
|
|
58
67
|
* @param sentArtifacts the artifacts the guard sent to preflight (for the digest bind)
|
|
59
68
|
*/
|
|
60
69
|
function evaluateEnvelope(response, envelope, executionAction, sentArtifacts) {
|
|
70
|
+
const top = (response && typeof response === 'object') ? response : {};
|
|
71
|
+
// 0. PRESENT-but-unrecognised action — before any decision map or reconciliation.
|
|
72
|
+
// Missing action is not handled here (readDecision maps legacy missing → closed Action).
|
|
73
|
+
const candidates = [executionAction, envelope.execution_action, top.execution_action];
|
|
74
|
+
for (const cand of candidates) {
|
|
75
|
+
if (cand === undefined || cand === null || cand === '')
|
|
76
|
+
continue; // missing — skip
|
|
77
|
+
if (!isAction(cand)) {
|
|
78
|
+
return {
|
|
79
|
+
verdict: 'fail-closed',
|
|
80
|
+
cause: 'EXECUTION_ACTION_UNRECOGNISED',
|
|
81
|
+
detail: `execution_action=${JSON.stringify(cand)} is present but not in the closed set`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
61
85
|
// 1. decision required + valid enum.
|
|
62
86
|
const dec = envelope.decision;
|
|
63
87
|
if (!isDecision(dec)) {
|
|
64
88
|
return { verdict: 'fail-closed', cause: 'DECISION_INCONSISTENT', detail: `decision=${JSON.stringify(dec)} is missing/invalid` };
|
|
65
89
|
}
|
|
90
|
+
// Known closed action from here (step 0 rejected unknowns).
|
|
91
|
+
const action = executionAction;
|
|
66
92
|
// 2. Strictest of every decision signal present (envelope, action-implied, top-level).
|
|
67
|
-
const signals = [dec, ACTION_TO_DECISION[
|
|
68
|
-
const top = (response && typeof response === 'object') ? response : {};
|
|
93
|
+
const signals = [dec, ACTION_TO_DECISION[action]];
|
|
69
94
|
if (isDecision(top.decision))
|
|
70
95
|
signals.push(top.decision);
|
|
71
96
|
if (isAction(top.execution_action))
|
|
@@ -76,8 +101,8 @@ function evaluateEnvelope(response, envelope, executionAction, sentArtifacts) {
|
|
|
76
101
|
return { verdict: 'block-strict', decision: effective };
|
|
77
102
|
}
|
|
78
103
|
// (effective is ALLOW or WARN — but ALSO require the envelope's own action to agree, else tamper.)
|
|
79
|
-
if (DECISION_TO_ACTION[dec] !==
|
|
80
|
-
return { verdict: 'fail-closed', cause: 'DECISION_INCONSISTENT', detail: `decision=${dec} ≠ execution_action=${
|
|
104
|
+
if (DECISION_TO_ACTION[dec] !== action) {
|
|
105
|
+
return { verdict: 'fail-closed', cause: 'DECISION_INCONSISTENT', detail: `decision=${dec} ≠ execution_action=${action}` };
|
|
81
106
|
}
|
|
82
107
|
// 3. §115 — safe_for_agent=false is NEVER executable, regardless of action.
|
|
83
108
|
if (envelope.safe_for_agent === false) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforcement-gate.js","sourceRoot":"","sources":["../../src/enforcement-gate.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"enforcement-gate.js","sourceRoot":"","sources":["../../src/enforcement-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guard-produced execution proof block.
|
|
3
|
+
*
|
|
4
|
+
* Assembled ONLY from state the guard itself observed while handling a call. Callers cannot supply
|
|
5
|
+
* fields into this object: builders take GuardOutcome-internal facts, not a host "proof" option.
|
|
6
|
+
* The returned object is deeply frozen so post-return mutation of proof fields is rejected.
|
|
7
|
+
*
|
|
8
|
+
* What this block proves (when the corresponding fields are present):
|
|
9
|
+
* - preflight happened → preflighted + decision_id
|
|
10
|
+
* - receipt was fresh → receipt.status === 'VERIFIED_CURRENT' + expires_at
|
|
11
|
+
* - scope matched → binds_to.operation + currently_authorized
|
|
12
|
+
* - ran on the guarded path → execution.enforced === true (runtime-asserted only with
|
|
13
|
+
* receipt.verified + preflighted; same invariant the types encode)
|
|
14
|
+
* - artifact checked vs executed → change_fp is WHAT WAS CHECKED; execution_result_hash is NOT a
|
|
15
|
+
* general claim that the applied side effect matched that fp
|
|
16
|
+
*
|
|
17
|
+
* What this block must never claim: that the change is safe, that the host cannot bypass the
|
|
18
|
+
* package, or that an absent field means compliance. Those limits are explicit on every block.
|
|
19
|
+
*/
|
|
20
|
+
import type { GuardVerdict } from './types.js';
|
|
21
|
+
/** Machine-readable schema id for this block. */
|
|
22
|
+
export declare const EXECUTION_PROOF_SPEC: "guard-execution-proof.v1";
|
|
23
|
+
/**
|
|
24
|
+
* Hash of the factory return value — only when the value is already byte-stable.
|
|
25
|
+
*
|
|
26
|
+
* Not hashed (and the block says so) when:
|
|
27
|
+
* - the factory did not run / threw / produced no result
|
|
28
|
+
* - the result is an object, array, number, boolean, null, bigint, symbol, function — any of these
|
|
29
|
+
* would require a serialization choice (key order, undefined, non-JSON values) that reformats
|
|
30
|
+
* the value rather than hashing the bytes the factory returned
|
|
31
|
+
*
|
|
32
|
+
* A hash of a string/Buffer does NOT prove the contract artifacts applied match change_fp_checked.
|
|
33
|
+
* That gap is named on limits.
|
|
34
|
+
*/
|
|
35
|
+
export type ExecutionResultHash = {
|
|
36
|
+
status: 'hashed';
|
|
37
|
+
algorithm: 'sha256';
|
|
38
|
+
value: string;
|
|
39
|
+
} | {
|
|
40
|
+
status: 'not_hashed';
|
|
41
|
+
reason: 'not_executed' | 'execution_threw' | 'result_not_byte_stable' | 'result_type_unsupported';
|
|
42
|
+
};
|
|
43
|
+
export type GuardExecutionProof = {
|
|
44
|
+
proof_spec: typeof EXECUTION_PROOF_SPEC;
|
|
45
|
+
/** Observed: true iff this call completed a preflight round-trip that produced a decision envelope. */
|
|
46
|
+
preflighted: boolean;
|
|
47
|
+
/** Observed from the decision envelope when preflighted; null otherwise. */
|
|
48
|
+
decision_id: string | null;
|
|
49
|
+
receipt: {
|
|
50
|
+
/**
|
|
51
|
+
* Observed: true only when the guard's verify+bind step branded the envelope
|
|
52
|
+
* (requires valid signature, status VERIFIED_CURRENT, body hash + fp + scope match).
|
|
53
|
+
*/
|
|
54
|
+
verified: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Observed derivation: bind requires status === 'VERIFIED_CURRENT', so verified ⇒ this value.
|
|
57
|
+
* null when the receipt was not verified (or no receipt path).
|
|
58
|
+
*/
|
|
59
|
+
status: 'VERIFIED_CURRENT' | null;
|
|
60
|
+
/** Observed from the envelope when present; null when no envelope. */
|
|
61
|
+
expires_at: string | null;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Observed from the authenticated envelope fields when an envelope exists.
|
|
65
|
+
* change_fp is the fingerprint of WHAT WAS CHECKED (preflighted), not of what the factory applied.
|
|
66
|
+
* null when no envelope (SKIPPED / unavailable without envelope).
|
|
67
|
+
*/
|
|
68
|
+
binds_to: {
|
|
69
|
+
operation: string | null;
|
|
70
|
+
change_fp: string | null;
|
|
71
|
+
} | null;
|
|
72
|
+
/**
|
|
73
|
+
* Observed at verify time: true iff receipt.verified (VERIFIED_CURRENT + bind).
|
|
74
|
+
* false when an envelope/receipt was present but did not verify.
|
|
75
|
+
* null when there was no receipt path to evaluate (SKIPPED, no envelope).
|
|
76
|
+
*/
|
|
77
|
+
currently_authorized: boolean | null;
|
|
78
|
+
execution: {
|
|
79
|
+
attempted: boolean;
|
|
80
|
+
executed: boolean;
|
|
81
|
+
enforced: boolean;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Observed: kind of the guard verdict that produced this outcome.
|
|
85
|
+
* On a blocked call this is how the block is named (BLOCK / APPROVAL / UNAVAILABLE / …).
|
|
86
|
+
*/
|
|
87
|
+
verdict_kind: string;
|
|
88
|
+
execution_result_hash: ExecutionResultHash;
|
|
89
|
+
/**
|
|
90
|
+
* Explicit non-claims. Readers that treat missing fields as "ok" are wrong; these are always set.
|
|
91
|
+
*/
|
|
92
|
+
limits: {
|
|
93
|
+
does_not_claim_change_safe: true;
|
|
94
|
+
does_not_claim_host_cannot_bypass: true;
|
|
95
|
+
does_not_claim_absent_field_is_compliance: true;
|
|
96
|
+
change_fp_is_what_was_checked_not_what_executed: true;
|
|
97
|
+
calls_outside_guarded_path_invisible: true;
|
|
98
|
+
execution_result_hash_is_not_artifact_match_proof: true;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
export type ProofBuildInput = {
|
|
102
|
+
preflighted: boolean;
|
|
103
|
+
executionAttempted: boolean;
|
|
104
|
+
executed: boolean;
|
|
105
|
+
enforced: boolean;
|
|
106
|
+
verdict: GuardVerdict;
|
|
107
|
+
/** Present only when executed:true (factory returned). */
|
|
108
|
+
result?: unknown;
|
|
109
|
+
/** Present only when factory threw. */
|
|
110
|
+
error?: unknown;
|
|
111
|
+
/** Optional conditional-write basis for the enforced+policy invariant. */
|
|
112
|
+
conditionalWriteBasis?: {
|
|
113
|
+
require_conditional_write: boolean;
|
|
114
|
+
write_style: boolean;
|
|
115
|
+
conditional_write: true | false | 'not_reported';
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Runtime twin of the type-level enforced⟺receiptVerified invariant.
|
|
120
|
+
* Throws if enforced:true is paired with anything other than receiptVerified+preflighted.
|
|
121
|
+
* When requireConditionalWrite+writeStyle: enforced:true also requires conditional_write:true
|
|
122
|
+
* (same refusal class as the permission gate — not a parallel path).
|
|
123
|
+
* The proof block is read by consumers that do not have our TypeScript brands.
|
|
124
|
+
*/
|
|
125
|
+
export declare function assertEnforcedReceiptInvariant(input: {
|
|
126
|
+
enforced: boolean;
|
|
127
|
+
preflighted: boolean;
|
|
128
|
+
receiptVerified: boolean;
|
|
129
|
+
/** Policy requireConditionalWrite for this call (optional; omit = not checked here). */
|
|
130
|
+
requireConditionalWrite?: boolean;
|
|
131
|
+
writeStyle?: boolean;
|
|
132
|
+
/** Host report: true | false | 'not_reported'. */
|
|
133
|
+
conditionalWrite?: true | false | 'not_reported';
|
|
134
|
+
}): void;
|
|
135
|
+
/**
|
|
136
|
+
* Honest byte hash of a factory return. Only string / Buffer / Uint8Array are hashed as raw bytes.
|
|
137
|
+
* Everything else is not_hashed with an explicit reason — never a JSON reformat hash.
|
|
138
|
+
*/
|
|
139
|
+
export declare function hashExecutionResult(result: unknown): ExecutionResultHash;
|
|
140
|
+
/**
|
|
141
|
+
* Build the proof block from guard-observed outcome facts only.
|
|
142
|
+
* Never accepts a caller-supplied proof object or partial field map.
|
|
143
|
+
*/
|
|
144
|
+
export declare function buildExecutionProof(input: ProofBuildInput): GuardExecutionProof;
|
|
145
|
+
//# sourceMappingURL=execution-proof.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-proof.d.ts","sourceRoot":"","sources":["../../src/execution-proof.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,iDAAiD;AACjD,eAAO,MAAM,oBAAoB,EAAG,0BAAmC,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACxD;IACE,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EACF,cAAc,GACd,iBAAiB,GACjB,wBAAwB,GACxB,yBAAyB,CAAC;CAC/B,CAAC;AAEN,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,OAAO,oBAAoB,CAAC;IACxC,uGAAuG;IACvG,WAAW,EAAE,OAAO,CAAC;IACrB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE;QACP;;;WAGG;QACH,QAAQ,EAAE,OAAO,CAAC;QAClB;;;WAGG;QACH,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;QAClC,sEAAsE;QACtE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,CAAC;IACF;;;;OAIG;IACH,QAAQ,EAAE;QACR,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT;;;;OAIG;IACH,oBAAoB,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,SAAS,EAAE;QACT,SAAS,EAAE,OAAO,CAAC;QACnB,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;IACF;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,mBAAmB,CAAC;IAC3C;;OAEG;IACH,MAAM,EAAE;QACN,0BAA0B,EAAE,IAAI,CAAC;QACjC,iCAAiC,EAAE,IAAI,CAAC;QACxC,yCAAyC,EAAE,IAAI,CAAC;QAChD,+CAA+C,EAAE,IAAI,CAAC;QACtD,oCAAoC,EAAE,IAAI,CAAC;QAC3C,iDAAiD,EAAE,IAAI,CAAC;KACzD,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0EAA0E;IAC1E,qBAAqB,CAAC,EAAE;QACtB,yBAAyB,EAAE,OAAO,CAAC;QACnC,WAAW,EAAE,OAAO,CAAC;QACrB,iBAAiB,EAAE,IAAI,GAAG,KAAK,GAAG,cAAc,CAAC;KAClD,CAAC;CACH,CAAC;AAWF;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE;IACpD,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,cAAc,CAAC;CAClD,GAAG,IAAI,CAeP;AA0BD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,mBAAmB,CAuBxE;AAeD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,mBAAmB,CA0D/E"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Guard-produced execution proof block.
|
|
4
|
+
*
|
|
5
|
+
* Assembled ONLY from state the guard itself observed while handling a call. Callers cannot supply
|
|
6
|
+
* fields into this object: builders take GuardOutcome-internal facts, not a host "proof" option.
|
|
7
|
+
* The returned object is deeply frozen so post-return mutation of proof fields is rejected.
|
|
8
|
+
*
|
|
9
|
+
* What this block proves (when the corresponding fields are present):
|
|
10
|
+
* - preflight happened → preflighted + decision_id
|
|
11
|
+
* - receipt was fresh → receipt.status === 'VERIFIED_CURRENT' + expires_at
|
|
12
|
+
* - scope matched → binds_to.operation + currently_authorized
|
|
13
|
+
* - ran on the guarded path → execution.enforced === true (runtime-asserted only with
|
|
14
|
+
* receipt.verified + preflighted; same invariant the types encode)
|
|
15
|
+
* - artifact checked vs executed → change_fp is WHAT WAS CHECKED; execution_result_hash is NOT a
|
|
16
|
+
* general claim that the applied side effect matched that fp
|
|
17
|
+
*
|
|
18
|
+
* What this block must never claim: that the change is safe, that the host cannot bypass the
|
|
19
|
+
* package, or that an absent field means compliance. Those limits are explicit on every block.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.EXECUTION_PROOF_SPEC = void 0;
|
|
23
|
+
exports.assertEnforcedReceiptInvariant = assertEnforcedReceiptInvariant;
|
|
24
|
+
exports.hashExecutionResult = hashExecutionResult;
|
|
25
|
+
exports.buildExecutionProof = buildExecutionProof;
|
|
26
|
+
const node_crypto_1 = require("node:crypto");
|
|
27
|
+
/** Machine-readable schema id for this block. */
|
|
28
|
+
exports.EXECUTION_PROOF_SPEC = 'guard-execution-proof.v1';
|
|
29
|
+
const LIMITS = Object.freeze({
|
|
30
|
+
does_not_claim_change_safe: true,
|
|
31
|
+
does_not_claim_host_cannot_bypass: true,
|
|
32
|
+
does_not_claim_absent_field_is_compliance: true,
|
|
33
|
+
change_fp_is_what_was_checked_not_what_executed: true,
|
|
34
|
+
calls_outside_guarded_path_invisible: true,
|
|
35
|
+
execution_result_hash_is_not_artifact_match_proof: true,
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* Runtime twin of the type-level enforced⟺receiptVerified invariant.
|
|
39
|
+
* Throws if enforced:true is paired with anything other than receiptVerified+preflighted.
|
|
40
|
+
* When requireConditionalWrite+writeStyle: enforced:true also requires conditional_write:true
|
|
41
|
+
* (same refusal class as the permission gate — not a parallel path).
|
|
42
|
+
* The proof block is read by consumers that do not have our TypeScript brands.
|
|
43
|
+
*/
|
|
44
|
+
function assertEnforcedReceiptInvariant(input) {
|
|
45
|
+
if (input.enforced === true) {
|
|
46
|
+
if (input.preflighted !== true || input.receiptVerified !== true) {
|
|
47
|
+
throw new Error('@coderifts/agent-guard: enforced:true without receiptVerified+preflighted (runtime invariant)');
|
|
48
|
+
}
|
|
49
|
+
if (input.requireConditionalWrite === true && input.writeStyle === true) {
|
|
50
|
+
if (input.conditionalWrite !== true) {
|
|
51
|
+
throw new Error('@coderifts/agent-guard: enforced:true without conditional_write:true under requireConditionalWrite (runtime invariant)');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function receiptVerifiedOf(verdict) {
|
|
57
|
+
if ('receiptVerified' in verdict && typeof verdict.receiptVerified === 'boolean') {
|
|
58
|
+
return verdict.receiptVerified === true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
function envelopeOf(verdict) {
|
|
63
|
+
if ('envelope' in verdict && verdict.envelope && typeof verdict.envelope === 'object') {
|
|
64
|
+
return verdict.envelope;
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Honest byte hash of a factory return. Only string / Buffer / Uint8Array are hashed as raw bytes.
|
|
70
|
+
* Everything else is not_hashed with an explicit reason — never a JSON reformat hash.
|
|
71
|
+
*/
|
|
72
|
+
function hashExecutionResult(result) {
|
|
73
|
+
if (typeof result === 'string') {
|
|
74
|
+
return {
|
|
75
|
+
status: 'hashed',
|
|
76
|
+
algorithm: 'sha256',
|
|
77
|
+
value: 'sha256:' + (0, node_crypto_1.createHash)('sha256').update(result, 'utf8').digest('hex'),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(result)) {
|
|
81
|
+
return {
|
|
82
|
+
status: 'hashed',
|
|
83
|
+
algorithm: 'sha256',
|
|
84
|
+
value: 'sha256:' + (0, node_crypto_1.createHash)('sha256').update(result).digest('hex'),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (result instanceof Uint8Array) {
|
|
88
|
+
return {
|
|
89
|
+
status: 'hashed',
|
|
90
|
+
algorithm: 'sha256',
|
|
91
|
+
value: 'sha256:' + (0, node_crypto_1.createHash)('sha256').update(result).digest('hex'),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return { status: 'not_hashed', reason: 'result_not_byte_stable' };
|
|
95
|
+
}
|
|
96
|
+
function executionResultHashOf(input) {
|
|
97
|
+
if (input.executionAttempted && !input.executed && 'error' in input && input.error !== undefined) {
|
|
98
|
+
return { status: 'not_hashed', reason: 'execution_threw' };
|
|
99
|
+
}
|
|
100
|
+
if (!input.executed) {
|
|
101
|
+
return { status: 'not_hashed', reason: 'not_executed' };
|
|
102
|
+
}
|
|
103
|
+
if (!('result' in input)) {
|
|
104
|
+
return { status: 'not_hashed', reason: 'result_type_unsupported' };
|
|
105
|
+
}
|
|
106
|
+
return hashExecutionResult(input.result);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Build the proof block from guard-observed outcome facts only.
|
|
110
|
+
* Never accepts a caller-supplied proof object or partial field map.
|
|
111
|
+
*/
|
|
112
|
+
function buildExecutionProof(input) {
|
|
113
|
+
const receiptVerified = receiptVerifiedOf(input.verdict);
|
|
114
|
+
const cwb = input.conditionalWriteBasis;
|
|
115
|
+
assertEnforcedReceiptInvariant({
|
|
116
|
+
enforced: input.enforced,
|
|
117
|
+
preflighted: input.preflighted,
|
|
118
|
+
receiptVerified,
|
|
119
|
+
requireConditionalWrite: cwb?.require_conditional_write,
|
|
120
|
+
writeStyle: cwb?.write_style,
|
|
121
|
+
conditionalWrite: cwb?.conditional_write,
|
|
122
|
+
});
|
|
123
|
+
const env = envelopeOf(input.verdict);
|
|
124
|
+
const hasEnvelope = env !== null;
|
|
125
|
+
let decision_id = null;
|
|
126
|
+
let expires_at = null;
|
|
127
|
+
let binds_to = null;
|
|
128
|
+
if (hasEnvelope && env) {
|
|
129
|
+
decision_id = typeof env.decision_id === 'string' ? env.decision_id : null;
|
|
130
|
+
expires_at = typeof env.expires_at === 'string' ? env.expires_at : null;
|
|
131
|
+
binds_to = Object.freeze({
|
|
132
|
+
operation: typeof env.operation === 'string' ? env.operation : null,
|
|
133
|
+
change_fp: typeof env.fingerprint === 'string' ? env.fingerprint : null,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// currently_authorized: only evaluable when a receipt path existed.
|
|
137
|
+
// verified ⇒ true (bind required VERIFIED_CURRENT). envelope present but not verified ⇒ false.
|
|
138
|
+
// no envelope (SKIPPED / some UNAVAILABLE) ⇒ null.
|
|
139
|
+
let currently_authorized = null;
|
|
140
|
+
if (hasEnvelope) {
|
|
141
|
+
currently_authorized = receiptVerified;
|
|
142
|
+
}
|
|
143
|
+
const proof = {
|
|
144
|
+
proof_spec: exports.EXECUTION_PROOF_SPEC,
|
|
145
|
+
preflighted: input.preflighted === true,
|
|
146
|
+
decision_id,
|
|
147
|
+
receipt: Object.freeze({
|
|
148
|
+
verified: receiptVerified,
|
|
149
|
+
status: receiptVerified ? 'VERIFIED_CURRENT' : null,
|
|
150
|
+
expires_at,
|
|
151
|
+
}),
|
|
152
|
+
binds_to: binds_to ? Object.freeze(binds_to) : null,
|
|
153
|
+
currently_authorized,
|
|
154
|
+
execution: Object.freeze({
|
|
155
|
+
attempted: input.executionAttempted === true,
|
|
156
|
+
executed: input.executed === true,
|
|
157
|
+
enforced: input.enforced === true,
|
|
158
|
+
}),
|
|
159
|
+
verdict_kind: typeof input.verdict?.kind === 'string' ? input.verdict.kind : 'UNKNOWN',
|
|
160
|
+
execution_result_hash: Object.freeze(executionResultHashOf(input)),
|
|
161
|
+
limits: LIMITS,
|
|
162
|
+
};
|
|
163
|
+
return freezeProof(proof);
|
|
164
|
+
}
|
|
165
|
+
function freezeProof(p) {
|
|
166
|
+
return Object.freeze(p);
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=execution-proof.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-proof.js","sourceRoot":"","sources":["../../src/execution-proof.ts"],"names":[],"mappings":"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"}
|