@paybond/kit 0.12.5 → 0.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/facade.d.ts +2 -0
- package/dist/agent/facade.js +10 -2
- package/dist/agent/guarded-agent.d.ts +3 -1
- package/dist/agent/guarded-agent.js +13 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/agent/instrument.d.ts +3 -0
- package/dist/agent/instrument.js +21 -10
- package/dist/agent/interceptor.js +19 -0
- package/dist/agent/types.d.ts +14 -0
- package/dist/agent-receipt-acta.d.ts +58 -0
- package/dist/agent-receipt-acta.js +140 -0
- package/dist/agent-receipt-inclusion.d.ts +40 -0
- package/dist/agent-receipt-inclusion.js +209 -0
- package/dist/agent-receipt-owner-disclosure.d.ts +71 -0
- package/dist/agent-receipt-owner-disclosure.js +277 -0
- package/dist/agent-receipt-pef.d.ts +69 -0
- package/dist/agent-receipt-pef.js +121 -0
- package/dist/agent-receipt-scitt.d.ts +50 -0
- package/dist/agent-receipt-scitt.js +382 -0
- package/dist/agent-receipt.d.ts +55 -0
- package/dist/agent-receipt.js +297 -4
- package/dist/claude-agents/config.d.ts +21 -2
- package/dist/claude-agents/config.js +37 -0
- package/dist/claude-agents/index.d.ts +1 -1
- package/dist/claude-agents/index.js +1 -1
- package/dist/cli/agent/demo-loaders.d.ts +1 -0
- package/dist/cli/agent/demo-loaders.js +12 -0
- package/dist/cli/command-spec.js +16 -1
- package/dist/cli/commands/agent.d.ts +4 -0
- package/dist/cli/commands/agent.js +107 -1
- package/dist/cli/help.js +4 -1
- package/dist/cloudflare-agents/config.d.ts +1 -1
- package/dist/cloudflare-agents/config.js +2 -2
- package/dist/google-adk/config.d.ts +36 -0
- package/dist/google-adk/config.js +172 -0
- package/dist/google-adk/index.d.ts +2 -0
- package/dist/google-adk/index.js +2 -0
- package/dist/google-adk/sandbox-demo.d.ts +32 -0
- package/dist/google-adk/sandbox-demo.js +104 -0
- package/dist/index.d.ts +10 -2
- package/dist/index.js +11 -3
- package/dist/init.js +29 -0
- package/dist/mcp-receipt-resource.js +3 -1
- package/dist/mcp-server.js +122 -2
- package/dist/policy/adapter-options.d.ts +9 -0
- package/dist/policy/adapter-options.js +11 -0
- package/dist/policy/index.d.ts +1 -0
- package/dist/policy/index.js +1 -0
- package/dist/policy/load.d.ts +7 -0
- package/dist/policy/load.js +13 -0
- package/dist/policy/merge.js +26 -0
- package/dist/policy/schema.d.ts +20 -0
- package/dist/policy/schema.js +34 -2
- package/dist/shopify/instrument.d.ts +8 -8
- package/dist/template-init.d.ts +2 -2
- package/dist/template-init.js +12 -4
- package/dist/vercel-ai/config.d.ts +2 -1
- package/dist/vercel-ai/config.js +2 -2
- package/dist/vercel-ai/index.d.ts +2 -1
- package/dist/vercel-ai/index.js +2 -1
- package/dist/vercel-ai/provider-executed.d.ts +7 -0
- package/dist/vercel-ai/provider-executed.js +20 -0
- package/dist/vercel-ai/tool-approval.d.ts +5 -0
- package/dist/vercel-ai/tool-approval.js +8 -1
- package/dist/vercel-ai/wrap-tools.d.ts +8 -1
- package/dist/vercel-ai/wrap-tools.js +17 -4
- package/package.json +13 -4
- package/templates/manifest.json +57 -12
- package/templates/openai-shopping-agent/package-lock.json +379 -14
- package/templates/openai-shopping-agent/package.json +2 -2
- package/templates/paybond-aws-operator/package-lock.json +376 -11
- package/templates/paybond-aws-operator/package.json +2 -2
- package/templates/paybond-claude-agents-demo/package-lock.json +379 -14
- package/templates/paybond-claude-agents-demo/package.json +2 -2
- package/templates/paybond-cloudflare-shopping-agent/.env.example +3 -0
- package/templates/paybond-cloudflare-shopping-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-cloudflare-shopping-agent/LICENSE +201 -0
- package/templates/paybond-cloudflare-shopping-agent/README.md +29 -0
- package/templates/paybond-cloudflare-shopping-agent/package-lock.json +2671 -0
- package/templates/paybond-cloudflare-shopping-agent/package.json +23 -0
- package/templates/paybond-cloudflare-shopping-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-cloudflare-shopping-agent/src/agent.ts +109 -0
- package/templates/paybond-cloudflare-shopping-agent/src/index.ts +22 -0
- package/templates/paybond-cloudflare-shopping-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-cloudflare-shopping-agent/tsconfig.json +13 -0
- package/templates/paybond-crewai-procurement-agent/.env.example +3 -0
- package/templates/paybond-crewai-procurement-agent/.github/workflows/smoke.yml +19 -0
- package/templates/paybond-crewai-procurement-agent/LICENSE +201 -0
- package/templates/paybond-crewai-procurement-agent/README.md +73 -0
- package/templates/paybond-crewai-procurement-agent/app.py +79 -0
- package/templates/paybond-crewai-procurement-agent/crew.py +117 -0
- package/templates/paybond-crewai-procurement-agent/package.json +6 -0
- package/templates/paybond-crewai-procurement-agent/paybond.policy.yaml +28 -0
- package/templates/paybond-crewai-procurement-agent/paybond_config.py +45 -0
- package/templates/paybond-crewai-procurement-agent/requirements.txt +2 -0
- package/templates/paybond-invoice-agent/requirements.txt +1 -1
- package/templates/paybond-mastra-travel-agent/package-lock.json +379 -14
- package/templates/paybond-mastra-travel-agent/package.json +2 -2
- package/templates/paybond-mcp-coding-agent/package-lock.json +376 -11
- package/templates/paybond-mcp-coding-agent/package.json +2 -2
- package/templates/paybond-openai-agents-demo/package-lock.json +379 -14
- package/templates/paybond-openai-agents-demo/package.json +2 -2
- package/templates/paybond-procurement-agent/package-lock.json +376 -11
- package/templates/paybond-procurement-agent/package.json +2 -2
- package/templates/paybond-shopify-shopping-agent/package-lock.json +376 -11
- package/templates/paybond-shopify-shopping-agent/package.json +2 -2
- package/templates/paybond-stripe-agent-demo/package-lock.json +376 -11
- package/templates/paybond-stripe-agent-demo/package.json +2 -2
- package/templates/paybond-travel-agent/package-lock.json +376 -11
- package/templates/paybond-travel-agent/package.json +2 -2
- package/templates/paybond-vercel-shopping-agent/package-lock.json +376 -11
- package/templates/paybond-vercel-shopping-agent/package.json +2 -2
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Evidence Frame (PEF) wrapper for agent-receipt audit handoff.
|
|
3
|
+
*
|
|
4
|
+
* Inspired by draft-hopley-x402-payment-evidence-frame: content-addressed
|
|
5
|
+
* `frame_id` over JCS(preimage), with `claim_type=paybond_agent_receipt_v1`.
|
|
6
|
+
* ARS core signing stays `ed25519-sha256-json-v1`; this adapter owns JCS.
|
|
7
|
+
*
|
|
8
|
+
* RFC 9421 detached signatures are reserved (`signature` extension point) and
|
|
9
|
+
* not populated by the builder in this release.
|
|
10
|
+
*/
|
|
11
|
+
import { createHash } from "node:crypto";
|
|
12
|
+
/** PEF claim taxonomy for Paybond agent receipts (interop adapter). */
|
|
13
|
+
export const PEF_CLAIM_TYPE_AGENT_RECEIPT_V1 = "paybond_agent_receipt_v1";
|
|
14
|
+
/** Canonicalisation URN pinned by the x402 PEF substrate. */
|
|
15
|
+
export const PEF_CANON_VERSION_JCS_RFC8785_V1 = "urn:x402:canonicalisation:jcs-rfc8785-v1";
|
|
16
|
+
export const PEF_VERSION_V1 = "1";
|
|
17
|
+
/** Inner receipt format label carried in the PEF envelope. */
|
|
18
|
+
export const PEF_RECEIPT_FORMAT_AGENT_RECEIPT_V1 = "paybond.agent_receipt_v1";
|
|
19
|
+
function canonicalizeJson(value) {
|
|
20
|
+
if (Array.isArray(value)) {
|
|
21
|
+
return value.map((item) => canonicalizeJson(item));
|
|
22
|
+
}
|
|
23
|
+
if (value && typeof value === "object") {
|
|
24
|
+
const record = value;
|
|
25
|
+
const keys = Object.keys(record).sort();
|
|
26
|
+
const out = {};
|
|
27
|
+
for (const key of keys) {
|
|
28
|
+
out[key] = canonicalizeJson(record[key]);
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
/** Returns RFC 8785 JCS bytes for an arbitrary JSON value. */
|
|
35
|
+
export function jcsCanonicalBytes(value) {
|
|
36
|
+
return new TextEncoder().encode(JSON.stringify(canonicalizeJson(value)));
|
|
37
|
+
}
|
|
38
|
+
function sha256Hex(data) {
|
|
39
|
+
return createHash("sha256").update(data).digest("hex");
|
|
40
|
+
}
|
|
41
|
+
function sha256Prefixed(hexDigest) {
|
|
42
|
+
return `sha256:${hexDigest}`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Computes `receipt_hash = sha256:` + hex(SHA-256(JCS(receipt))).
|
|
46
|
+
*/
|
|
47
|
+
export function agentReceiptPefReceiptHash(receipt) {
|
|
48
|
+
return sha256Prefixed(sha256Hex(jcsCanonicalBytes(receipt)));
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Builds the PEF preimage object (excludes `frame_id` and `signature`).
|
|
52
|
+
*/
|
|
53
|
+
export function agentReceiptPefPreimage(input, receiptHash) {
|
|
54
|
+
const provider = input.frameProviderDid.trim();
|
|
55
|
+
if (!provider) {
|
|
56
|
+
throw new Error("pef: frame_provider_did is required");
|
|
57
|
+
}
|
|
58
|
+
if (!Number.isInteger(input.frameTimestampMs) || input.frameTimestampMs < 0) {
|
|
59
|
+
throw new Error("pef: frame_timestamp_ms must be a non-negative integer");
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
canon_version: PEF_CANON_VERSION_JCS_RFC8785_V1,
|
|
63
|
+
claim_type: PEF_CLAIM_TYPE_AGENT_RECEIPT_V1,
|
|
64
|
+
frame_provider_did: provider,
|
|
65
|
+
frame_timestamp_ms: input.frameTimestampMs,
|
|
66
|
+
pef_version: PEF_VERSION_V1,
|
|
67
|
+
receipt: input.receipt,
|
|
68
|
+
receipt_format: PEF_RECEIPT_FORMAT_AGENT_RECEIPT_V1,
|
|
69
|
+
receipt_hash: receiptHash,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Derives `frame_id = sha256:` + hex(SHA-256(JCS(preimage))).
|
|
74
|
+
*/
|
|
75
|
+
export function agentReceiptPefFrameId(preimage) {
|
|
76
|
+
return sha256Prefixed(sha256Hex(jcsCanonicalBytes(preimage)));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Builds a content-addressed PEF wrapper around an ARS receipt.
|
|
80
|
+
*
|
|
81
|
+
* Does not modify or re-sign the inner ARS envelope.
|
|
82
|
+
*/
|
|
83
|
+
export function buildAgentReceiptPefFrame(input) {
|
|
84
|
+
const receiptHash = agentReceiptPefReceiptHash(input.receipt);
|
|
85
|
+
const preimage = agentReceiptPefPreimage(input, receiptHash);
|
|
86
|
+
const frameId = agentReceiptPefFrameId(preimage);
|
|
87
|
+
return {
|
|
88
|
+
canon_version: PEF_CANON_VERSION_JCS_RFC8785_V1,
|
|
89
|
+
claim_type: PEF_CLAIM_TYPE_AGENT_RECEIPT_V1,
|
|
90
|
+
frame_id: frameId,
|
|
91
|
+
frame_provider_did: String(preimage.frame_provider_did),
|
|
92
|
+
frame_timestamp_ms: input.frameTimestampMs,
|
|
93
|
+
pef_version: PEF_VERSION_V1,
|
|
94
|
+
receipt: input.receipt,
|
|
95
|
+
receipt_format: PEF_RECEIPT_FORMAT_AGENT_RECEIPT_V1,
|
|
96
|
+
receipt_hash: receiptHash,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Recomputes `frame_id` / `receipt_hash` and checks they match the frame.
|
|
101
|
+
*
|
|
102
|
+
* @throws Error when hashes do not match
|
|
103
|
+
*/
|
|
104
|
+
export function verifyAgentReceiptPefFrameId(frame) {
|
|
105
|
+
const expectedReceiptHash = agentReceiptPefReceiptHash(frame.receipt);
|
|
106
|
+
if (frame.receipt_hash !== expectedReceiptHash) {
|
|
107
|
+
throw new Error("pef: receipt_hash mismatch");
|
|
108
|
+
}
|
|
109
|
+
const preimage = agentReceiptPefPreimage({
|
|
110
|
+
receipt: frame.receipt,
|
|
111
|
+
frameProviderDid: frame.frame_provider_did,
|
|
112
|
+
frameTimestampMs: frame.frame_timestamp_ms,
|
|
113
|
+
}, expectedReceiptHash);
|
|
114
|
+
const expectedFrameId = agentReceiptPefFrameId(preimage);
|
|
115
|
+
if (frame.frame_id !== expectedFrameId) {
|
|
116
|
+
throw new Error("pef: frame_id mismatch");
|
|
117
|
+
}
|
|
118
|
+
if (frame.claim_type !== PEF_CLAIM_TYPE_AGENT_RECEIPT_V1) {
|
|
119
|
+
throw new Error("pef: unexpected claim_type");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SCITT COSE_Sign1 export adapter for verified ARS digests.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the ARS `message_digest_sha256` as a COSE_Sign1 Signed Statement
|
|
5
|
+
* payload suitable for registration with an external Transparency Service.
|
|
6
|
+
* ARS itself stays JSON-native; this adapter does not change compose/sign.
|
|
7
|
+
*
|
|
8
|
+
* Implements a minimal deterministic CBOR encoder for EdDSA COSE_Sign1
|
|
9
|
+
* (RFC 9052) without introducing a large COSE dependency.
|
|
10
|
+
*/
|
|
11
|
+
/** Export envelope kind for Kit/Go/Rust parity. */
|
|
12
|
+
export declare const AGENT_RECEIPT_SCITT_EXPORT_KIND_V1 = "paybond.agent_receipt_scitt_export_v1";
|
|
13
|
+
/** Statement kind encoded as the COSE_Sign1 payload (JCS JSON bytes). */
|
|
14
|
+
export declare const AGENT_RECEIPT_SCITT_STATEMENT_KIND_V1 = "paybond.agent_receipt_scitt_statement_v1";
|
|
15
|
+
/** COSE algorithm identifier for EdDSA (RFC 9053). */
|
|
16
|
+
export declare const COSE_ALG_EDDSA = -8;
|
|
17
|
+
export type AgentReceiptScittStatementV1 = {
|
|
18
|
+
kind: typeof AGENT_RECEIPT_SCITT_STATEMENT_KIND_V1;
|
|
19
|
+
receipt_id: string;
|
|
20
|
+
message_digest_sha256_hex: string;
|
|
21
|
+
};
|
|
22
|
+
export type BuildAgentReceiptScittExportInput = {
|
|
23
|
+
receiptId: string;
|
|
24
|
+
messageDigestSha256Hex: string;
|
|
25
|
+
/** 32-byte Ed25519 seed or PKCS8-compatible raw seed via Node crypto. */
|
|
26
|
+
signingPrivateKeySeedHex: string;
|
|
27
|
+
/** Issuer claim (iss) for SCITT CWT claims. */
|
|
28
|
+
issuer: string;
|
|
29
|
+
/** Optional key id placed in protected header `kid`. */
|
|
30
|
+
kid?: string;
|
|
31
|
+
};
|
|
32
|
+
export type AgentReceiptScittExportV1 = {
|
|
33
|
+
kind: typeof AGENT_RECEIPT_SCITT_EXPORT_KIND_V1;
|
|
34
|
+
receipt_id: string;
|
|
35
|
+
message_digest_sha256_hex: string;
|
|
36
|
+
signing_public_key_ed25519_hex: string;
|
|
37
|
+
issuer: string;
|
|
38
|
+
kid?: string;
|
|
39
|
+
/** Tagged COSE_Sign1 (CBOR tag 18) as lowercase hex. */
|
|
40
|
+
cose_sign1_tag18_hex: string;
|
|
41
|
+
statement: AgentReceiptScittStatementV1;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Builds a SCITT-oriented COSE_Sign1 export for a verified ARS message digest.
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildAgentReceiptScittExport(input: BuildAgentReceiptScittExportInput): AgentReceiptScittExportV1;
|
|
47
|
+
/**
|
|
48
|
+
* Verifies a SCITT export envelope: COSE_Sign1 EdDSA over the statement payload.
|
|
49
|
+
*/
|
|
50
|
+
export declare function verifyAgentReceiptScittExport(exportDoc: AgentReceiptScittExportV1): void;
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SCITT COSE_Sign1 export adapter for verified ARS digests.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the ARS `message_digest_sha256` as a COSE_Sign1 Signed Statement
|
|
5
|
+
* payload suitable for registration with an external Transparency Service.
|
|
6
|
+
* ARS itself stays JSON-native; this adapter does not change compose/sign.
|
|
7
|
+
*
|
|
8
|
+
* Implements a minimal deterministic CBOR encoder for EdDSA COSE_Sign1
|
|
9
|
+
* (RFC 9052) without introducing a large COSE dependency.
|
|
10
|
+
*/
|
|
11
|
+
import { createPrivateKey, createPublicKey, sign as nodeSign, verify as nodeVerify } from "node:crypto";
|
|
12
|
+
import { ensureEd25519Sha512Sync } from "./ed25519-sync.js";
|
|
13
|
+
/** Export envelope kind for Kit/Go/Rust parity. */
|
|
14
|
+
export const AGENT_RECEIPT_SCITT_EXPORT_KIND_V1 = "paybond.agent_receipt_scitt_export_v1";
|
|
15
|
+
/** Statement kind encoded as the COSE_Sign1 payload (JCS JSON bytes). */
|
|
16
|
+
export const AGENT_RECEIPT_SCITT_STATEMENT_KIND_V1 = "paybond.agent_receipt_scitt_statement_v1";
|
|
17
|
+
/** COSE algorithm identifier for EdDSA (RFC 9053). */
|
|
18
|
+
export const COSE_ALG_EDDSA = -8;
|
|
19
|
+
/** COSE header label: alg. */
|
|
20
|
+
const COSE_HEADER_ALG = 1;
|
|
21
|
+
/** COSE header label: kid. */
|
|
22
|
+
const COSE_HEADER_KID = 4;
|
|
23
|
+
/** COSE header label: CWT Claims (RFC 9597). */
|
|
24
|
+
const COSE_HEADER_CWT_CLAIMS = 15;
|
|
25
|
+
/** CWT claim: iss. */
|
|
26
|
+
const CWT_CLAIM_ISS = 1;
|
|
27
|
+
/** CWT claim: sub. */
|
|
28
|
+
const CWT_CLAIM_SUB = 2;
|
|
29
|
+
function canonicalizeJson(value) {
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
return value.map((item) => canonicalizeJson(item));
|
|
32
|
+
}
|
|
33
|
+
if (value && typeof value === "object") {
|
|
34
|
+
const record = value;
|
|
35
|
+
const keys = Object.keys(record).sort();
|
|
36
|
+
const out = {};
|
|
37
|
+
for (const key of keys) {
|
|
38
|
+
out[key] = canonicalizeJson(record[key]);
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
function jcsBytes(value) {
|
|
45
|
+
return new TextEncoder().encode(JSON.stringify(canonicalizeJson(value)));
|
|
46
|
+
}
|
|
47
|
+
function requireHex64(value, field) {
|
|
48
|
+
const normalized = value.trim().toLowerCase();
|
|
49
|
+
if (!/^[0-9a-f]{64}$/.test(normalized)) {
|
|
50
|
+
throw new Error(`scitt export: ${field} must be a lowercase 64-char hex digest`);
|
|
51
|
+
}
|
|
52
|
+
return normalized;
|
|
53
|
+
}
|
|
54
|
+
function hexToBytes(hex) {
|
|
55
|
+
const out = new Uint8Array(hex.length / 2);
|
|
56
|
+
for (let i = 0; i < out.length; i += 1) {
|
|
57
|
+
out[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
function bytesToHex(bytes) {
|
|
62
|
+
return Buffer.from(bytes).toString("hex");
|
|
63
|
+
}
|
|
64
|
+
function concatBytes(...parts) {
|
|
65
|
+
const total = parts.reduce((sum, part) => sum + part.length, 0);
|
|
66
|
+
const out = new Uint8Array(total);
|
|
67
|
+
let offset = 0;
|
|
68
|
+
for (const part of parts) {
|
|
69
|
+
out.set(part, offset);
|
|
70
|
+
offset += part.length;
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
function encodeCborUint(value) {
|
|
75
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
76
|
+
throw new Error("scitt export: CBOR uint must be a non-negative integer");
|
|
77
|
+
}
|
|
78
|
+
if (value < 24) {
|
|
79
|
+
return Uint8Array.of(value);
|
|
80
|
+
}
|
|
81
|
+
if (value < 0x100) {
|
|
82
|
+
return Uint8Array.of(24, value);
|
|
83
|
+
}
|
|
84
|
+
if (value < 0x10000) {
|
|
85
|
+
return Uint8Array.of(25, (value >> 8) & 0xff, value & 0xff);
|
|
86
|
+
}
|
|
87
|
+
if (value < 0x100000000) {
|
|
88
|
+
return Uint8Array.of(26, (value >>> 24) & 0xff, (value >>> 16) & 0xff, (value >>> 8) & 0xff, value & 0xff);
|
|
89
|
+
}
|
|
90
|
+
throw new Error("scitt export: CBOR uint too large");
|
|
91
|
+
}
|
|
92
|
+
function encodeCborNint(value) {
|
|
93
|
+
// Major type 1: -1 - n
|
|
94
|
+
const n = -1 - value;
|
|
95
|
+
if (n < 24) {
|
|
96
|
+
return Uint8Array.of(0x20 | n);
|
|
97
|
+
}
|
|
98
|
+
if (n < 0x100) {
|
|
99
|
+
return Uint8Array.of(0x38, n);
|
|
100
|
+
}
|
|
101
|
+
if (n < 0x10000) {
|
|
102
|
+
return Uint8Array.of(0x39, (n >> 8) & 0xff, n & 0xff);
|
|
103
|
+
}
|
|
104
|
+
throw new Error("scitt export: CBOR nint too large");
|
|
105
|
+
}
|
|
106
|
+
function encodeCborInt(value) {
|
|
107
|
+
if (!Number.isInteger(value)) {
|
|
108
|
+
throw new Error("scitt export: CBOR int must be an integer");
|
|
109
|
+
}
|
|
110
|
+
return value >= 0 ? encodeCborUint(value) : encodeCborNint(value);
|
|
111
|
+
}
|
|
112
|
+
function encodeCborBstr(bytes) {
|
|
113
|
+
const header = bytes.length < 24
|
|
114
|
+
? Uint8Array.of(0x40 | bytes.length)
|
|
115
|
+
: bytes.length < 0x100
|
|
116
|
+
? Uint8Array.of(0x58, bytes.length)
|
|
117
|
+
: bytes.length < 0x10000
|
|
118
|
+
? Uint8Array.of(0x59, (bytes.length >> 8) & 0xff, bytes.length & 0xff)
|
|
119
|
+
: (() => {
|
|
120
|
+
throw new Error("scitt export: CBOR bstr too large");
|
|
121
|
+
})();
|
|
122
|
+
return concatBytes(header, bytes);
|
|
123
|
+
}
|
|
124
|
+
function encodeCborTstr(value) {
|
|
125
|
+
const bytes = new TextEncoder().encode(value);
|
|
126
|
+
const header = bytes.length < 24
|
|
127
|
+
? Uint8Array.of(0x60 | bytes.length)
|
|
128
|
+
: bytes.length < 0x100
|
|
129
|
+
? Uint8Array.of(0x78, bytes.length)
|
|
130
|
+
: bytes.length < 0x10000
|
|
131
|
+
? Uint8Array.of(0x79, (bytes.length >> 8) & 0xff, bytes.length & 0xff)
|
|
132
|
+
: (() => {
|
|
133
|
+
throw new Error("scitt export: CBOR tstr too large");
|
|
134
|
+
})();
|
|
135
|
+
return concatBytes(header, bytes);
|
|
136
|
+
}
|
|
137
|
+
function encodeCborArray(items) {
|
|
138
|
+
const header = items.length < 24
|
|
139
|
+
? Uint8Array.of(0x80 | items.length)
|
|
140
|
+
: Uint8Array.of(0x98, items.length);
|
|
141
|
+
return concatBytes(header, ...items);
|
|
142
|
+
}
|
|
143
|
+
function encodeCborMap(entries) {
|
|
144
|
+
// Deterministic: sort by encoded key bytes (RFC 8949 §4.2.1).
|
|
145
|
+
const encoded = entries.map(([key, value]) => {
|
|
146
|
+
const keyBytes = typeof key === "number" ? encodeCborInt(key) : encodeCborTstr(key);
|
|
147
|
+
return { keyBytes, value };
|
|
148
|
+
});
|
|
149
|
+
encoded.sort((a, b) => {
|
|
150
|
+
const min = Math.min(a.keyBytes.length, b.keyBytes.length);
|
|
151
|
+
for (let i = 0; i < min; i += 1) {
|
|
152
|
+
const diff = a.keyBytes[i] - b.keyBytes[i];
|
|
153
|
+
if (diff !== 0) {
|
|
154
|
+
return diff;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return a.keyBytes.length - b.keyBytes.length;
|
|
158
|
+
});
|
|
159
|
+
const header = encoded.length < 24
|
|
160
|
+
? Uint8Array.of(0xa0 | encoded.length)
|
|
161
|
+
: Uint8Array.of(0xb8, encoded.length);
|
|
162
|
+
return concatBytes(header, ...encoded.flatMap((entry) => [entry.keyBytes, entry.value]));
|
|
163
|
+
}
|
|
164
|
+
function encodeCborTag(tag, item) {
|
|
165
|
+
const header = tag < 24
|
|
166
|
+
? Uint8Array.of(0xc0 | tag)
|
|
167
|
+
: tag < 0x100
|
|
168
|
+
? Uint8Array.of(0xd8, tag)
|
|
169
|
+
: (() => {
|
|
170
|
+
throw new Error("scitt export: CBOR tag too large");
|
|
171
|
+
})();
|
|
172
|
+
return concatBytes(header, item);
|
|
173
|
+
}
|
|
174
|
+
function ed25519KeyFromSeed(seedHex) {
|
|
175
|
+
const seed = hexToBytes(requireHex64(seedHex, "signing_private_key_seed_hex"));
|
|
176
|
+
const privateKey = createPrivateKey({
|
|
177
|
+
key: Buffer.concat([
|
|
178
|
+
Buffer.from("302e020100300506032b657004220420", "hex"),
|
|
179
|
+
Buffer.from(seed),
|
|
180
|
+
]),
|
|
181
|
+
format: "der",
|
|
182
|
+
type: "pkcs8",
|
|
183
|
+
});
|
|
184
|
+
const pub = createPublicKey(privateKey).export({ type: "spki", format: "der" });
|
|
185
|
+
return {
|
|
186
|
+
privateKey,
|
|
187
|
+
publicKeyHex: pub.subarray(pub.length - 32).toString("hex"),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function buildProtectedHeader(issuer, subject, kid) {
|
|
191
|
+
const cwtClaims = encodeCborMap([
|
|
192
|
+
[CWT_CLAIM_ISS, encodeCborTstr(issuer)],
|
|
193
|
+
[CWT_CLAIM_SUB, encodeCborTstr(subject)],
|
|
194
|
+
]);
|
|
195
|
+
const entries = [
|
|
196
|
+
[COSE_HEADER_ALG, encodeCborInt(COSE_ALG_EDDSA)],
|
|
197
|
+
[COSE_HEADER_CWT_CLAIMS, cwtClaims],
|
|
198
|
+
];
|
|
199
|
+
if (kid && kid.trim()) {
|
|
200
|
+
entries.push([COSE_HEADER_KID, encodeCborTstr(kid.trim())]);
|
|
201
|
+
}
|
|
202
|
+
return encodeCborMap(entries);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Builds a SCITT-oriented COSE_Sign1 export for a verified ARS message digest.
|
|
206
|
+
*/
|
|
207
|
+
export function buildAgentReceiptScittExport(input) {
|
|
208
|
+
ensureEd25519Sha512Sync();
|
|
209
|
+
const receiptId = input.receiptId.trim();
|
|
210
|
+
if (!receiptId) {
|
|
211
|
+
throw new Error("scitt export: receipt_id is required");
|
|
212
|
+
}
|
|
213
|
+
const issuer = input.issuer.trim();
|
|
214
|
+
if (!issuer) {
|
|
215
|
+
throw new Error("scitt export: issuer is required");
|
|
216
|
+
}
|
|
217
|
+
const messageDigest = requireHex64(input.messageDigestSha256Hex, "message_digest_sha256_hex");
|
|
218
|
+
const statement = {
|
|
219
|
+
kind: AGENT_RECEIPT_SCITT_STATEMENT_KIND_V1,
|
|
220
|
+
receipt_id: receiptId,
|
|
221
|
+
message_digest_sha256_hex: messageDigest,
|
|
222
|
+
};
|
|
223
|
+
const payload = jcsBytes(statement);
|
|
224
|
+
// SCITT subject is receipt_id; iss is the configured issuer.
|
|
225
|
+
const protectedHeader = buildProtectedHeader(issuer, receiptId, input.kid);
|
|
226
|
+
const protectedBstr = encodeCborBstr(protectedHeader);
|
|
227
|
+
const payloadBstr = encodeCborBstr(payload);
|
|
228
|
+
const sigStructure = encodeCborArray([
|
|
229
|
+
encodeCborTstr("Signature1"),
|
|
230
|
+
protectedBstr,
|
|
231
|
+
encodeCborBstr(new Uint8Array(0)),
|
|
232
|
+
payloadBstr,
|
|
233
|
+
]);
|
|
234
|
+
const { privateKey, publicKeyHex } = ed25519KeyFromSeed(input.signingPrivateKeySeedHex);
|
|
235
|
+
const signature = nodeSign(null, Buffer.from(sigStructure), privateKey);
|
|
236
|
+
const coseSign1 = encodeCborArray([
|
|
237
|
+
encodeCborBstr(protectedHeader),
|
|
238
|
+
encodeCborMap([]),
|
|
239
|
+
encodeCborBstr(payload),
|
|
240
|
+
encodeCborBstr(new Uint8Array(signature)),
|
|
241
|
+
]);
|
|
242
|
+
const tagged = encodeCborTag(18, coseSign1);
|
|
243
|
+
const exportDoc = {
|
|
244
|
+
kind: AGENT_RECEIPT_SCITT_EXPORT_KIND_V1,
|
|
245
|
+
receipt_id: receiptId,
|
|
246
|
+
message_digest_sha256_hex: messageDigest,
|
|
247
|
+
signing_public_key_ed25519_hex: publicKeyHex,
|
|
248
|
+
issuer,
|
|
249
|
+
cose_sign1_tag18_hex: bytesToHex(tagged),
|
|
250
|
+
statement,
|
|
251
|
+
};
|
|
252
|
+
if (input.kid?.trim()) {
|
|
253
|
+
exportDoc.kid = input.kid.trim();
|
|
254
|
+
}
|
|
255
|
+
return exportDoc;
|
|
256
|
+
}
|
|
257
|
+
function readCborLength(bytes, offset, additional) {
|
|
258
|
+
if (additional < 24) {
|
|
259
|
+
return { length: additional, next: offset };
|
|
260
|
+
}
|
|
261
|
+
if (additional === 24) {
|
|
262
|
+
return { length: bytes[offset], next: offset + 1 };
|
|
263
|
+
}
|
|
264
|
+
if (additional === 25) {
|
|
265
|
+
return {
|
|
266
|
+
length: (bytes[offset] << 8) | bytes[offset + 1],
|
|
267
|
+
next: offset + 2,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
throw new Error("scitt export: unsupported CBOR length");
|
|
271
|
+
}
|
|
272
|
+
function decodeCborItem(bytes, offset) {
|
|
273
|
+
const initial = bytes[offset];
|
|
274
|
+
const major = initial >> 5;
|
|
275
|
+
const additional = initial & 0x1f;
|
|
276
|
+
let cursor = offset + 1;
|
|
277
|
+
if (major === 0) {
|
|
278
|
+
const { length, next } = readCborLength(bytes, cursor, additional);
|
|
279
|
+
return { value: length, next, raw: bytes.subarray(offset, next) };
|
|
280
|
+
}
|
|
281
|
+
if (major === 1) {
|
|
282
|
+
const { length, next } = readCborLength(bytes, cursor, additional);
|
|
283
|
+
return { value: -1 - length, next, raw: bytes.subarray(offset, next) };
|
|
284
|
+
}
|
|
285
|
+
if (major === 2 || major === 3) {
|
|
286
|
+
const { length, next } = readCborLength(bytes, cursor, additional);
|
|
287
|
+
const end = next + length;
|
|
288
|
+
const slice = bytes.subarray(next, end);
|
|
289
|
+
return {
|
|
290
|
+
value: major === 2 ? slice : new TextDecoder().decode(slice),
|
|
291
|
+
next: end,
|
|
292
|
+
raw: bytes.subarray(offset, end),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
if (major === 4) {
|
|
296
|
+
const { length, next } = readCborLength(bytes, cursor, additional);
|
|
297
|
+
cursor = next;
|
|
298
|
+
const items = [];
|
|
299
|
+
const start = offset;
|
|
300
|
+
for (let i = 0; i < length; i += 1) {
|
|
301
|
+
const decoded = decodeCborItem(bytes, cursor);
|
|
302
|
+
items.push(decoded.value);
|
|
303
|
+
cursor = decoded.next;
|
|
304
|
+
}
|
|
305
|
+
return { value: items, next: cursor, raw: bytes.subarray(start, cursor) };
|
|
306
|
+
}
|
|
307
|
+
if (major === 5) {
|
|
308
|
+
const { length, next } = readCborLength(bytes, cursor, additional);
|
|
309
|
+
cursor = next;
|
|
310
|
+
const map = new Map();
|
|
311
|
+
const start = offset;
|
|
312
|
+
for (let i = 0; i < length; i += 1) {
|
|
313
|
+
const key = decodeCborItem(bytes, cursor);
|
|
314
|
+
const val = decodeCborItem(bytes, key.next);
|
|
315
|
+
map.set(key.value, val.value);
|
|
316
|
+
cursor = val.next;
|
|
317
|
+
}
|
|
318
|
+
return { value: map, next: cursor, raw: bytes.subarray(start, cursor) };
|
|
319
|
+
}
|
|
320
|
+
if (major === 6) {
|
|
321
|
+
const { length: tag, next } = readCborLength(bytes, cursor, additional);
|
|
322
|
+
const inner = decodeCborItem(bytes, next);
|
|
323
|
+
return {
|
|
324
|
+
value: { tag, value: inner.value },
|
|
325
|
+
next: inner.next,
|
|
326
|
+
raw: bytes.subarray(offset, inner.next),
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
throw new Error(`scitt export: unsupported CBOR major type ${major}`);
|
|
330
|
+
}
|
|
331
|
+
function decodeTaggedCoseSign1(taggedHex) {
|
|
332
|
+
const bytes = hexToBytes(taggedHex.trim().toLowerCase());
|
|
333
|
+
const decoded = decodeCborItem(bytes, 0);
|
|
334
|
+
const tagged = decoded.value;
|
|
335
|
+
if (!tagged || tagged.tag !== 18 || !Array.isArray(tagged.value) || tagged.value.length !== 4) {
|
|
336
|
+
throw new Error("scitt export: expected CBOR tag 18 COSE_Sign1 array");
|
|
337
|
+
}
|
|
338
|
+
const [protectedRaw, , payload, signature] = tagged.value;
|
|
339
|
+
if (!(protectedRaw instanceof Uint8Array) || !(payload instanceof Uint8Array) || !(signature instanceof Uint8Array)) {
|
|
340
|
+
throw new Error("scitt export: COSE_Sign1 fields must be bstrs");
|
|
341
|
+
}
|
|
342
|
+
return { protectedRaw, payload, signature };
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Verifies a SCITT export envelope: COSE_Sign1 EdDSA over the statement payload.
|
|
346
|
+
*/
|
|
347
|
+
export function verifyAgentReceiptScittExport(exportDoc) {
|
|
348
|
+
ensureEd25519Sha512Sync();
|
|
349
|
+
if (exportDoc.kind !== AGENT_RECEIPT_SCITT_EXPORT_KIND_V1) {
|
|
350
|
+
throw new Error("scitt export: unexpected kind");
|
|
351
|
+
}
|
|
352
|
+
const digest = requireHex64(exportDoc.message_digest_sha256_hex, "message_digest_sha256_hex");
|
|
353
|
+
if (exportDoc.statement.message_digest_sha256_hex !== digest) {
|
|
354
|
+
throw new Error("scitt export: statement digest mismatch");
|
|
355
|
+
}
|
|
356
|
+
if (exportDoc.statement.receipt_id !== exportDoc.receipt_id) {
|
|
357
|
+
throw new Error("scitt export: statement receipt_id mismatch");
|
|
358
|
+
}
|
|
359
|
+
const expectedPayload = jcsBytes(exportDoc.statement);
|
|
360
|
+
const { protectedRaw, payload, signature } = decodeTaggedCoseSign1(exportDoc.cose_sign1_tag18_hex);
|
|
361
|
+
if (bytesToHex(payload) !== bytesToHex(expectedPayload)) {
|
|
362
|
+
throw new Error("scitt export: COSE payload mismatch");
|
|
363
|
+
}
|
|
364
|
+
const sigStructure = encodeCborArray([
|
|
365
|
+
encodeCborTstr("Signature1"),
|
|
366
|
+
encodeCborBstr(protectedRaw),
|
|
367
|
+
encodeCborBstr(new Uint8Array(0)),
|
|
368
|
+
encodeCborBstr(payload),
|
|
369
|
+
]);
|
|
370
|
+
const pub = createPublicKey({
|
|
371
|
+
key: Buffer.concat([
|
|
372
|
+
Buffer.from("302a300506032b6570032100", "hex"),
|
|
373
|
+
Buffer.from(hexToBytes(requireHex64(exportDoc.signing_public_key_ed25519_hex, "signing_public_key_ed25519_hex"))),
|
|
374
|
+
]),
|
|
375
|
+
format: "der",
|
|
376
|
+
type: "spki",
|
|
377
|
+
});
|
|
378
|
+
const ok = nodeVerify(null, Buffer.from(sigStructure), pub, Buffer.from(signature));
|
|
379
|
+
if (!ok) {
|
|
380
|
+
throw new Error("scitt export: COSE_Sign1 signature invalid");
|
|
381
|
+
}
|
|
382
|
+
}
|
package/dist/agent-receipt.d.ts
CHANGED
|
@@ -10,6 +10,13 @@ export declare const AGENT_RECEIPT_SIGNING_KEYS_WELL_KNOWN_PATH = "/.well-known/
|
|
|
10
10
|
export declare const PAYBOND_AGENT_RECEIPT_ATTESTATIONS_HEADER = "x-paybond-agent-receipt-attestations";
|
|
11
11
|
/** Optional agent run id bound to the attestation header for server-side audit. */
|
|
12
12
|
export declare const PAYBOND_AGENT_RECEIPT_SOURCE_RUN_HEADER = "x-paybond-agent-run-id";
|
|
13
|
+
/** AP2 signed-mandate digest kind promoted into authorization.mandate_digest_sha256_hex. */
|
|
14
|
+
export declare const EXTERNAL_ATTESTATION_KIND_AGENT_MANDATE_V1 = "agent_mandate_v1";
|
|
15
|
+
export declare const SETTLEMENT_OUTCOME_SETTLED = "SETTLED";
|
|
16
|
+
export declare const SETTLEMENT_OUTCOME_PENDING_FINALITY = "PENDING_FINALITY";
|
|
17
|
+
export declare const SETTLEMENT_OUTCOME_REVERSED = "REVERSED";
|
|
18
|
+
export declare const SETTLEMENT_OUTCOME_FAILED = "FAILED";
|
|
19
|
+
export type AgentReceiptSettlementOutcome = typeof SETTLEMENT_OUTCOME_SETTLED | typeof SETTLEMENT_OUTCOME_PENDING_FINALITY | typeof SETTLEMENT_OUTCOME_REVERSED | typeof SETTLEMENT_OUTCOME_FAILED;
|
|
13
20
|
export type AgentReceiptAgentV1 = {
|
|
14
21
|
operator_did: string;
|
|
15
22
|
model_family: string;
|
|
@@ -35,6 +42,10 @@ export type AgentReceiptAuthorizationV1 = {
|
|
|
35
42
|
requested_spend_cents: number;
|
|
36
43
|
currency: string;
|
|
37
44
|
reason_codes?: string[];
|
|
45
|
+
mandate_digest_sha256_hex?: string;
|
|
46
|
+
mandate_reference_id?: string;
|
|
47
|
+
/** Reserved ZK policy-compliance proof digest — schema-ready; not emitted by compose yet. */
|
|
48
|
+
zk_policy_proof_digest_sha256_hex?: string;
|
|
38
49
|
};
|
|
39
50
|
export type AgentReceiptExecutionV1 = {
|
|
40
51
|
run_id: string;
|
|
@@ -47,6 +58,8 @@ export type AgentReceiptExecutionV1 = {
|
|
|
47
58
|
started_at: string;
|
|
48
59
|
completed_at: string;
|
|
49
60
|
duration_ms?: number;
|
|
61
|
+
/** Reserved TEE attestation digest — schema-ready; not emitted by compose yet. */
|
|
62
|
+
tee_attestation_digest_sha256_hex?: string;
|
|
50
63
|
};
|
|
51
64
|
export type AgentReceiptMerchantV1 = {
|
|
52
65
|
payee_did: string;
|
|
@@ -72,6 +85,8 @@ export type AgentReceiptOutcomeV1 = {
|
|
|
72
85
|
harbor_state: string;
|
|
73
86
|
spend_reservation_outcome?: "consumed" | "released" | "pending" | "none";
|
|
74
87
|
predicate_passed?: boolean;
|
|
88
|
+
/** Categorical settlement claim for intent_terminal scope only. */
|
|
89
|
+
settlement_outcome?: AgentReceiptSettlementOutcome;
|
|
75
90
|
};
|
|
76
91
|
export type AgentReceiptReferencesV1 = {
|
|
77
92
|
intent_id: string;
|
|
@@ -90,6 +105,15 @@ export type AgentReceiptOperatorAttestationV1 = {
|
|
|
90
105
|
message_digest_sha256_hex: string;
|
|
91
106
|
ed25519_signature_hex: string;
|
|
92
107
|
};
|
|
108
|
+
export type AgentReceiptContinuityV1 = {
|
|
109
|
+
prev_message_digest_sha256_hex?: string;
|
|
110
|
+
sequence_number: number;
|
|
111
|
+
run_id: string;
|
|
112
|
+
};
|
|
113
|
+
export declare const AGENT_RECEIPT_VALIDITY_TIER_OPERATIONAL = "operational";
|
|
114
|
+
export declare const AGENT_RECEIPT_VALIDITY_TIER_PRIMARY = "primary";
|
|
115
|
+
export declare const AGENT_RECEIPT_VALIDITY_TIER_ATTESTED = "attested";
|
|
116
|
+
export type AgentReceiptValidityTier = typeof AGENT_RECEIPT_VALIDITY_TIER_OPERATIONAL | typeof AGENT_RECEIPT_VALIDITY_TIER_PRIMARY | typeof AGENT_RECEIPT_VALIDITY_TIER_ATTESTED;
|
|
93
117
|
export type AgentReceiptV1 = {
|
|
94
118
|
schema_version: number;
|
|
95
119
|
kind: string;
|
|
@@ -106,6 +130,7 @@ export type AgentReceiptV1 = {
|
|
|
106
130
|
outcome: AgentReceiptOutcomeV1;
|
|
107
131
|
references: AgentReceiptReferencesV1;
|
|
108
132
|
external_attestations: AgentReceiptExternalAttestationV1[];
|
|
133
|
+
continuity?: AgentReceiptContinuityV1;
|
|
109
134
|
operator_attestation?: AgentReceiptOperatorAttestationV1;
|
|
110
135
|
signing_algorithm: string;
|
|
111
136
|
message_digest_sha256_hex: string;
|
|
@@ -141,11 +166,41 @@ export type VerifyAgentReceiptV1Options = {
|
|
|
141
166
|
* When true, require any operator_attestation signing key to appear in
|
|
142
167
|
* trustedOperatorPublicKeys (e.g. tenant middleware attach recognition keys). The
|
|
143
168
|
* operator_did binding to authorization.agent.operator_did is always enforced.
|
|
169
|
+
*
|
|
170
|
+
* For `trustMode: "tenant_registry"`, defaults to true when an operator_attestation
|
|
171
|
+
* is present (empty trusted set rejects the attestation). Gateway JWKS / gateway
|
|
172
|
+
* trust mode leaves this opt-in.
|
|
144
173
|
*/
|
|
145
174
|
verifyOperatorAgainstRegistry?: boolean;
|
|
146
175
|
/** Lowercase operator signing pubkeys accepted when the registry check is enabled. */
|
|
147
176
|
trustedOperatorPublicKeys?: readonly string[];
|
|
177
|
+
/**
|
|
178
|
+
* Mirror of Gateway `?trust_mode=`. `tenant_registry` defaults operator registry
|
|
179
|
+
* checks on when an operator_attestation is present.
|
|
180
|
+
*/
|
|
181
|
+
trustMode?: "gateway" | "tenant_registry";
|
|
182
|
+
/**
|
|
183
|
+
* Required validity tier: `operational` (default), `primary`, or `attested`.
|
|
184
|
+
* `attested` forces operator registry checks.
|
|
185
|
+
*/
|
|
186
|
+
requiredValidityTier?: AgentReceiptValidityTier | string;
|
|
187
|
+
/**
|
|
188
|
+
* When set, require `continuity.prev_message_digest_sha256_hex` to equal this digest.
|
|
189
|
+
*/
|
|
190
|
+
expectedPriorMessageDigestHex?: string;
|
|
148
191
|
};
|
|
192
|
+
/** Returns the highest validity tier met under the given registry options. */
|
|
193
|
+
export declare function achievedValidityTier(receipt: AgentReceiptV1, options?: Pick<VerifyAgentReceiptV1Options, "trustedOperatorPublicKeys">): AgentReceiptValidityTier;
|
|
194
|
+
/**
|
|
195
|
+
* Builds the next continuity link from a prior signed action receipt for the same run.
|
|
196
|
+
* When `prior` is omitted, returns sequence 1 with no prev digest.
|
|
197
|
+
*/
|
|
198
|
+
export declare function continuityFromPrior(runId: string, prior?: AgentReceiptV1 | null): AgentReceiptContinuityV1;
|
|
199
|
+
/**
|
|
200
|
+
* Validates an ordered set of action receipts that declare continuity.
|
|
201
|
+
* Receipts without continuity are ignored. Broken links fail closed.
|
|
202
|
+
*/
|
|
203
|
+
export declare function verifyContinuityChain(receipts: readonly AgentReceiptV1[]): void;
|
|
149
204
|
/** Validates structure, receipt_id derivation, digest, and detached Ed25519 signature. */
|
|
150
205
|
export declare function verifyAgentReceiptV1(receipt: AgentReceiptV1, options?: VerifyAgentReceiptV1Options): Promise<AgentReceiptV1>;
|
|
151
206
|
/** Validate raw JSON (schema + forbidden fields) then verify signature. */
|