@adcp/sdk 14.0.0-beta.11 → 14.0.0-beta.12

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.
Files changed (94) hide show
  1. package/bin/adcp-storyboard-sandbox.js +16 -0
  2. package/bin/adcp.js +28 -30
  3. package/dist/lib/schemas/index.d.mts +385 -1
  4. package/dist/lib/schemas/index.d.ts +385 -1
  5. package/dist/lib/schemas/index.d.ts.map +1 -1
  6. package/dist/lib/schemas/index.js +13 -0
  7. package/dist/lib/schemas/index.js.map +1 -1
  8. package/dist/lib/schemas/index.mjs +11 -0
  9. package/dist/lib/schemas/index.mjs.map +1 -1
  10. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  11. package/dist/lib/signing/agent-context.d.mts +1 -0
  12. package/dist/lib/signing/agent-context.d.ts +1 -0
  13. package/dist/lib/signing/agent-context.d.ts.map +1 -1
  14. package/dist/lib/signing/agent-context.js +37 -2
  15. package/dist/lib/signing/agent-context.js.map +1 -1
  16. package/dist/lib/signing/agent-context.mjs +38 -3
  17. package/dist/lib/signing/agent-context.mjs.map +1 -1
  18. package/dist/lib/signing/agent-fetch.d.mts +1 -2
  19. package/dist/lib/signing/agent-fetch.d.ts +1 -2
  20. package/dist/lib/signing/agent-fetch.d.ts.map +1 -1
  21. package/dist/lib/signing/agent-fetch.js +2 -0
  22. package/dist/lib/signing/agent-fetch.js.map +1 -1
  23. package/dist/lib/signing/agent-fetch.mjs +2 -0
  24. package/dist/lib/signing/agent-fetch.mjs.map +1 -1
  25. package/dist/lib/signing/agent-resolver/etld.js.map +1 -1
  26. package/dist/lib/signing/agent-resolver/etld.mjs.map +1 -1
  27. package/dist/lib/testing/client.d.mts +6 -0
  28. package/dist/lib/testing/client.d.ts +6 -0
  29. package/dist/lib/testing/client.d.ts.map +1 -1
  30. package/dist/lib/testing/client.js +76 -4
  31. package/dist/lib/testing/client.js.map +1 -1
  32. package/dist/lib/testing/client.mjs +75 -4
  33. package/dist/lib/testing/client.mjs.map +1 -1
  34. package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
  35. package/dist/lib/testing/compliance/comply.js +6 -0
  36. package/dist/lib/testing/compliance/comply.js.map +1 -1
  37. package/dist/lib/testing/compliance/comply.mjs +7 -1
  38. package/dist/lib/testing/compliance/comply.mjs.map +1 -1
  39. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.mts +15 -0
  40. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.ts +16 -0
  41. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.ts.map +1 -0
  42. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.js +106 -0
  43. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.js.map +1 -0
  44. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.mjs +82 -0
  45. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.mjs.map +1 -0
  46. package/dist/lib/testing/storyboard/request-signing/test-kit.d.mts +15 -0
  47. package/dist/lib/testing/storyboard/request-signing/test-kit.d.ts +15 -0
  48. package/dist/lib/testing/storyboard/request-signing/test-kit.d.ts.map +1 -1
  49. package/dist/lib/testing/storyboard/request-signing/test-kit.js +58 -0
  50. package/dist/lib/testing/storyboard/request-signing/test-kit.js.map +1 -1
  51. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs +58 -0
  52. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs.map +1 -1
  53. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
  54. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
  55. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts.map +1 -1
  56. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +7 -1
  57. package/dist/lib/testing/storyboard/request-signing/vector-loader.js.map +1 -1
  58. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +6 -1
  59. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
  60. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  61. package/dist/lib/testing/storyboard/runner.js +10 -1
  62. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  63. package/dist/lib/testing/storyboard/runner.mjs +10 -1
  64. package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
  65. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  66. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  67. package/dist/lib/testing/types.d.mts +10 -0
  68. package/dist/lib/testing/types.d.ts +10 -0
  69. package/dist/lib/testing/types.d.ts.map +1 -1
  70. package/dist/lib/testing/types.js.map +1 -1
  71. package/dist/lib/types/comply-test-controller.d.ts +1 -14
  72. package/dist/lib/types/core.generated.d.mts +1 -1
  73. package/dist/lib/types/core.generated.d.ts +1 -1
  74. package/dist/lib/types/core.generated.d.ts.map +1 -1
  75. package/dist/lib/types/core.generated.js.map +1 -1
  76. package/dist/lib/types/get-products.d.ts +1 -14
  77. package/dist/lib/types/schemas.generated.d.ts +4 -56
  78. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  79. package/dist/lib/types/schemas.generated.js +2 -2
  80. package/dist/lib/types/schemas.generated.js.map +1 -1
  81. package/dist/lib/types/schemas.generated.mjs +2 -2
  82. package/dist/lib/types/schemas.generated.mjs.map +1 -1
  83. package/dist/lib/types/tools.generated.d.mts +1 -1
  84. package/dist/lib/types/tools.generated.d.ts +1 -1
  85. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  86. package/dist/lib/types/tools.generated.js.map +1 -1
  87. package/dist/lib/version.d.mts +3 -3
  88. package/dist/lib/version.d.ts +3 -3
  89. package/dist/lib/version.js +3 -3
  90. package/dist/lib/version.js.map +1 -1
  91. package/dist/lib/version.mjs +3 -3
  92. package/dist/lib/version.mjs.map +1 -1
  93. package/docs/llms.txt +1 -1
  94. package/package.json +2 -2
@@ -0,0 +1,15 @@
1
+ import type { TestOptions } from '../../types.mjs';
2
+ export interface FunctionalDispatchLoadOptions {
3
+ complianceDir?: string;
4
+ version?: string;
5
+ }
6
+ /**
7
+ * Attach the shared compliance signer for ordinary functional dispatch.
8
+ *
9
+ * The bundled private scalar is deliberately public test material, so it is
10
+ * auto-loaded only for an explicit sandbox run. `disable_sandbox` always wins.
11
+ * A caller-provided signer is already operator-authorized. Its identity and
12
+ * provider are preserved; in an in-scope sandbox run, the contract's
13
+ * supported-operation policy is applied without loading the bundled key.
14
+ */
15
+ export declare function applyFunctionalRequestSigning<T extends TestOptions>(options: T, loadOptions?: FunctionalDispatchLoadOptions): T;
@@ -0,0 +1,16 @@
1
+ import type { TestOptions } from '../../types';
2
+ export interface FunctionalDispatchLoadOptions {
3
+ complianceDir?: string;
4
+ version?: string;
5
+ }
6
+ /**
7
+ * Attach the shared compliance signer for ordinary functional dispatch.
8
+ *
9
+ * The bundled private scalar is deliberately public test material, so it is
10
+ * auto-loaded only for an explicit sandbox run. `disable_sandbox` always wins.
11
+ * A caller-provided signer is already operator-authorized. Its identity and
12
+ * provider are preserved; in an in-scope sandbox run, the contract's
13
+ * supported-operation policy is applied without loading the bundled key.
14
+ */
15
+ export declare function applyFunctionalRequestSigning<T extends TestOptions>(options: T, loadOptions?: FunctionalDispatchLoadOptions): T;
16
+ //# sourceMappingURL=functional-dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functional-dispatch.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/functional-dispatch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,MAAM,WAAW,6BAA6B;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,SAAS,WAAW,EACjE,OAAO,EAAE,CAAC,EACV,WAAW,GAAE,6BAAkC,GAC9C,CAAC,CAoFH"}
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var functional_dispatch_exports = {};
20
+ __export(functional_dispatch_exports, {
21
+ applyFunctionalRequestSigning: () => applyFunctionalRequestSigning
22
+ });
23
+ module.exports = __toCommonJS(functional_dispatch_exports);
24
+ var import_vector_loader = require('./vector-loader.js');
25
+ var import_test_kit = require('./test-kit.js');
26
+ function applyFunctionalRequestSigning(options, loadOptions = {}) {
27
+ if (options.sandbox !== true || options.disable_sandbox === true) return options;
28
+ const contract = (0, import_test_kit.loadSignedRequestsRunnerContract)(loadOptions);
29
+ const dispatch = contract?.functional_dispatch;
30
+ if (!dispatch) return options;
31
+ if (contract.endpoint_scope !== "sandbox") {
32
+ throw new Error(
33
+ `functional request signing refused: signed-requests runner endpoint_scope must be "sandbox", got "${contract.endpoint_scope}"`
34
+ );
35
+ }
36
+ if (!dispatch.operation_selection.sign_required_for) {
37
+ throw new Error("functional request signing contract must enable sign_required_for");
38
+ }
39
+ if (!dispatch.operation_selection.sign_supported_for) {
40
+ throw new Error("functional request signing contract must enable sign_supported_for");
41
+ }
42
+ if (dispatch.bootstrap_operations_unsigned.length !== 1 || dispatch.bootstrap_operations_unsigned[0] !== "get_adcp_capabilities") {
43
+ throw new Error("functional request signing supports only unsigned bootstrap discovery via get_adcp_capabilities");
44
+ }
45
+ if (!dispatch.preserve_transport_auth || !dispatch.fresh_signature_per_dispatch) {
46
+ throw new Error(
47
+ "functional request signing contract must preserve transport auth and mint a fresh signature per dispatch"
48
+ );
49
+ }
50
+ const suppliedSigning = options.functional_request_signing;
51
+ if (suppliedSigning) {
52
+ if (suppliedSigning.always_sign?.includes("get_adcp_capabilities")) {
53
+ throw new Error("functional request signing requires unsigned bootstrap discovery via get_adcp_capabilities");
54
+ }
55
+ if (suppliedSigning.sign_supported === true) return options;
56
+ return {
57
+ ...options,
58
+ functional_request_signing: { ...suppliedSigning, sign_supported: true }
59
+ };
60
+ }
61
+ const declaredKey = contract.runner_signing_keys.find((entry) => entry.keyid === dispatch.signing_keyid);
62
+ if (!declaredKey) {
63
+ throw new Error(
64
+ `functional request signing key "${dispatch.signing_keyid}" is not declared in runner_signing_keys`
65
+ );
66
+ }
67
+ const key = (0, import_vector_loader.findKey)((0, import_vector_loader.loadRequestSigningKeys)(loadOptions), dispatch.signing_keyid);
68
+ const alg = key.crv === "Ed25519" ? "ed25519" : key.crv === "P-256" ? "ecdsa-p256-sha256" : void 0;
69
+ if (!alg || alg !== declaredKey.alg) {
70
+ throw new Error(
71
+ `functional request signing key "${key.kid}" does not match declared algorithm "${declaredKey.alg}"`
72
+ );
73
+ }
74
+ if (key.adcp_use !== "request-signing") {
75
+ throw new Error(`functional request signing key "${key.kid}" must have adcp_use="request-signing"`);
76
+ }
77
+ if (contract.stateful_vector_contract.revocation.pre_revoked_keyid === key.kid) {
78
+ throw new Error(`functional request signing key "${key.kid}" is the contract's pre-revoked key`);
79
+ }
80
+ const privateKey = {
81
+ kid: key.kid,
82
+ kty: key.kty,
83
+ ...key.crv && { crv: key.crv },
84
+ ...key.alg && { alg: key.alg },
85
+ ...key.use && { use: key.use },
86
+ key_ops: ["sign"],
87
+ ...key.adcp_use && { adcp_use: key.adcp_use },
88
+ ...key.x && { x: key.x },
89
+ ...key.y && { y: key.y },
90
+ d: key.private_d
91
+ };
92
+ const signing = {
93
+ kind: "inline",
94
+ kid: key.kid,
95
+ alg,
96
+ private_key: privateKey,
97
+ agent_url: dispatch.signer_agent_url,
98
+ sign_supported: dispatch.operation_selection.sign_supported_for
99
+ };
100
+ return { ...options, functional_request_signing: signing };
101
+ }
102
+ // Annotate the CommonJS export names for ESM import in node:
103
+ 0 && (module.exports = {
104
+ applyFunctionalRequestSigning
105
+ });
106
+ //# sourceMappingURL=functional-dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/functional-dispatch.ts"],"sourcesContent":["import type { AgentRequestSigningConfig, AdcpPrivateJsonWebKey } from '../../../types/adcp';\nimport type { TestOptions } from '../../types';\nimport { loadRequestSigningKeys, findKey } from './vector-loader';\nimport { loadSignedRequestsRunnerContract } from './test-kit';\n\nexport interface FunctionalDispatchLoadOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Attach the shared compliance signer for ordinary functional dispatch.\n *\n * The bundled private scalar is deliberately public test material, so it is\n * auto-loaded only for an explicit sandbox run. `disable_sandbox` always wins.\n * A caller-provided signer is already operator-authorized. Its identity and\n * provider are preserved; in an in-scope sandbox run, the contract's\n * supported-operation policy is applied without loading the bundled key.\n */\nexport function applyFunctionalRequestSigning<T extends TestOptions>(\n options: T,\n loadOptions: FunctionalDispatchLoadOptions = {}\n): T {\n if (options.sandbox !== true || options.disable_sandbox === true) return options;\n\n const contract = loadSignedRequestsRunnerContract(loadOptions);\n const dispatch = contract?.functional_dispatch;\n // Older compliance bundles predate functional signing. Keep beta.8's\n // post-dispatch not_applicable compatibility behavior for those bundles.\n if (!dispatch) return options;\n if (contract.endpoint_scope !== 'sandbox') {\n throw new Error(\n `functional request signing refused: signed-requests runner endpoint_scope must be \"sandbox\", got \"${contract.endpoint_scope}\"`\n );\n }\n if (!dispatch.operation_selection.sign_required_for) {\n throw new Error('functional request signing contract must enable sign_required_for');\n }\n if (!dispatch.operation_selection.sign_supported_for) {\n throw new Error('functional request signing contract must enable sign_supported_for');\n }\n if (\n dispatch.bootstrap_operations_unsigned.length !== 1 ||\n dispatch.bootstrap_operations_unsigned[0] !== 'get_adcp_capabilities'\n ) {\n throw new Error('functional request signing supports only unsigned bootstrap discovery via get_adcp_capabilities');\n }\n if (!dispatch.preserve_transport_auth || !dispatch.fresh_signature_per_dispatch) {\n throw new Error(\n 'functional request signing contract must preserve transport auth and mint a fresh signature per dispatch'\n );\n }\n\n const suppliedSigning = options.functional_request_signing;\n if (suppliedSigning) {\n if (suppliedSigning.always_sign?.includes('get_adcp_capabilities')) {\n throw new Error('functional request signing requires unsigned bootstrap discovery via get_adcp_capabilities');\n }\n if (suppliedSigning.sign_supported === true) return options;\n return {\n ...options,\n functional_request_signing: { ...suppliedSigning, sign_supported: true },\n };\n }\n\n const declaredKey = contract.runner_signing_keys.find(entry => entry.keyid === dispatch.signing_keyid);\n if (!declaredKey) {\n throw new Error(\n `functional request signing key \"${dispatch.signing_keyid}\" is not declared in runner_signing_keys`\n );\n }\n const key = findKey(loadRequestSigningKeys(loadOptions), dispatch.signing_keyid);\n const alg = key.crv === 'Ed25519' ? 'ed25519' : key.crv === 'P-256' ? 'ecdsa-p256-sha256' : undefined;\n if (!alg || alg !== declaredKey.alg) {\n throw new Error(\n `functional request signing key \"${key.kid}\" does not match declared algorithm \"${declaredKey.alg}\"`\n );\n }\n if (key.adcp_use !== 'request-signing') {\n throw new Error(`functional request signing key \"${key.kid}\" must have adcp_use=\"request-signing\"`);\n }\n if (contract.stateful_vector_contract.revocation.pre_revoked_keyid === key.kid) {\n throw new Error(`functional request signing key \"${key.kid}\" is the contract's pre-revoked key`);\n }\n\n const privateKey: AdcpPrivateJsonWebKey = {\n kid: key.kid,\n kty: key.kty,\n ...(key.crv && { crv: key.crv }),\n ...(key.alg && { alg: key.alg }),\n ...(key.use && { use: key.use }),\n key_ops: ['sign'],\n ...(key.adcp_use && { adcp_use: key.adcp_use }),\n ...(key.x && { x: key.x }),\n ...(key.y && { y: key.y }),\n d: key.private_d,\n };\n const signing: AgentRequestSigningConfig = {\n kind: 'inline',\n kid: key.kid,\n alg,\n private_key: privateKey,\n agent_url: dispatch.signer_agent_url,\n sign_supported: dispatch.operation_selection.sign_supported_for,\n };\n return { ...options, functional_request_signing: signing };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,82 @@
1
+ import { loadRequestSigningKeys, findKey } from "./vector-loader.mjs";
2
+ import { loadSignedRequestsRunnerContract } from "./test-kit.mjs";
3
+ function applyFunctionalRequestSigning(options, loadOptions = {}) {
4
+ if (options.sandbox !== true || options.disable_sandbox === true) return options;
5
+ const contract = loadSignedRequestsRunnerContract(loadOptions);
6
+ const dispatch = contract?.functional_dispatch;
7
+ if (!dispatch) return options;
8
+ if (contract.endpoint_scope !== "sandbox") {
9
+ throw new Error(
10
+ `functional request signing refused: signed-requests runner endpoint_scope must be "sandbox", got "${contract.endpoint_scope}"`
11
+ );
12
+ }
13
+ if (!dispatch.operation_selection.sign_required_for) {
14
+ throw new Error("functional request signing contract must enable sign_required_for");
15
+ }
16
+ if (!dispatch.operation_selection.sign_supported_for) {
17
+ throw new Error("functional request signing contract must enable sign_supported_for");
18
+ }
19
+ if (dispatch.bootstrap_operations_unsigned.length !== 1 || dispatch.bootstrap_operations_unsigned[0] !== "get_adcp_capabilities") {
20
+ throw new Error("functional request signing supports only unsigned bootstrap discovery via get_adcp_capabilities");
21
+ }
22
+ if (!dispatch.preserve_transport_auth || !dispatch.fresh_signature_per_dispatch) {
23
+ throw new Error(
24
+ "functional request signing contract must preserve transport auth and mint a fresh signature per dispatch"
25
+ );
26
+ }
27
+ const suppliedSigning = options.functional_request_signing;
28
+ if (suppliedSigning) {
29
+ if (suppliedSigning.always_sign?.includes("get_adcp_capabilities")) {
30
+ throw new Error("functional request signing requires unsigned bootstrap discovery via get_adcp_capabilities");
31
+ }
32
+ if (suppliedSigning.sign_supported === true) return options;
33
+ return {
34
+ ...options,
35
+ functional_request_signing: { ...suppliedSigning, sign_supported: true }
36
+ };
37
+ }
38
+ const declaredKey = contract.runner_signing_keys.find((entry) => entry.keyid === dispatch.signing_keyid);
39
+ if (!declaredKey) {
40
+ throw new Error(
41
+ `functional request signing key "${dispatch.signing_keyid}" is not declared in runner_signing_keys`
42
+ );
43
+ }
44
+ const key = findKey(loadRequestSigningKeys(loadOptions), dispatch.signing_keyid);
45
+ const alg = key.crv === "Ed25519" ? "ed25519" : key.crv === "P-256" ? "ecdsa-p256-sha256" : void 0;
46
+ if (!alg || alg !== declaredKey.alg) {
47
+ throw new Error(
48
+ `functional request signing key "${key.kid}" does not match declared algorithm "${declaredKey.alg}"`
49
+ );
50
+ }
51
+ if (key.adcp_use !== "request-signing") {
52
+ throw new Error(`functional request signing key "${key.kid}" must have adcp_use="request-signing"`);
53
+ }
54
+ if (contract.stateful_vector_contract.revocation.pre_revoked_keyid === key.kid) {
55
+ throw new Error(`functional request signing key "${key.kid}" is the contract's pre-revoked key`);
56
+ }
57
+ const privateKey = {
58
+ kid: key.kid,
59
+ kty: key.kty,
60
+ ...key.crv && { crv: key.crv },
61
+ ...key.alg && { alg: key.alg },
62
+ ...key.use && { use: key.use },
63
+ key_ops: ["sign"],
64
+ ...key.adcp_use && { adcp_use: key.adcp_use },
65
+ ...key.x && { x: key.x },
66
+ ...key.y && { y: key.y },
67
+ d: key.private_d
68
+ };
69
+ const signing = {
70
+ kind: "inline",
71
+ kid: key.kid,
72
+ alg,
73
+ private_key: privateKey,
74
+ agent_url: dispatch.signer_agent_url,
75
+ sign_supported: dispatch.operation_selection.sign_supported_for
76
+ };
77
+ return { ...options, functional_request_signing: signing };
78
+ }
79
+ export {
80
+ applyFunctionalRequestSigning
81
+ };
82
+ //# sourceMappingURL=functional-dispatch.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/functional-dispatch.ts"],"sourcesContent":["import type { AgentRequestSigningConfig, AdcpPrivateJsonWebKey } from '../../../types/adcp';\nimport type { TestOptions } from '../../types';\nimport { loadRequestSigningKeys, findKey } from './vector-loader';\nimport { loadSignedRequestsRunnerContract } from './test-kit';\n\nexport interface FunctionalDispatchLoadOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Attach the shared compliance signer for ordinary functional dispatch.\n *\n * The bundled private scalar is deliberately public test material, so it is\n * auto-loaded only for an explicit sandbox run. `disable_sandbox` always wins.\n * A caller-provided signer is already operator-authorized. Its identity and\n * provider are preserved; in an in-scope sandbox run, the contract's\n * supported-operation policy is applied without loading the bundled key.\n */\nexport function applyFunctionalRequestSigning<T extends TestOptions>(\n options: T,\n loadOptions: FunctionalDispatchLoadOptions = {}\n): T {\n if (options.sandbox !== true || options.disable_sandbox === true) return options;\n\n const contract = loadSignedRequestsRunnerContract(loadOptions);\n const dispatch = contract?.functional_dispatch;\n // Older compliance bundles predate functional signing. Keep beta.8's\n // post-dispatch not_applicable compatibility behavior for those bundles.\n if (!dispatch) return options;\n if (contract.endpoint_scope !== 'sandbox') {\n throw new Error(\n `functional request signing refused: signed-requests runner endpoint_scope must be \"sandbox\", got \"${contract.endpoint_scope}\"`\n );\n }\n if (!dispatch.operation_selection.sign_required_for) {\n throw new Error('functional request signing contract must enable sign_required_for');\n }\n if (!dispatch.operation_selection.sign_supported_for) {\n throw new Error('functional request signing contract must enable sign_supported_for');\n }\n if (\n dispatch.bootstrap_operations_unsigned.length !== 1 ||\n dispatch.bootstrap_operations_unsigned[0] !== 'get_adcp_capabilities'\n ) {\n throw new Error('functional request signing supports only unsigned bootstrap discovery via get_adcp_capabilities');\n }\n if (!dispatch.preserve_transport_auth || !dispatch.fresh_signature_per_dispatch) {\n throw new Error(\n 'functional request signing contract must preserve transport auth and mint a fresh signature per dispatch'\n );\n }\n\n const suppliedSigning = options.functional_request_signing;\n if (suppliedSigning) {\n if (suppliedSigning.always_sign?.includes('get_adcp_capabilities')) {\n throw new Error('functional request signing requires unsigned bootstrap discovery via get_adcp_capabilities');\n }\n if (suppliedSigning.sign_supported === true) return options;\n return {\n ...options,\n functional_request_signing: { ...suppliedSigning, sign_supported: true },\n };\n }\n\n const declaredKey = contract.runner_signing_keys.find(entry => entry.keyid === dispatch.signing_keyid);\n if (!declaredKey) {\n throw new Error(\n `functional request signing key \"${dispatch.signing_keyid}\" is not declared in runner_signing_keys`\n );\n }\n const key = findKey(loadRequestSigningKeys(loadOptions), dispatch.signing_keyid);\n const alg = key.crv === 'Ed25519' ? 'ed25519' : key.crv === 'P-256' ? 'ecdsa-p256-sha256' : undefined;\n if (!alg || alg !== declaredKey.alg) {\n throw new Error(\n `functional request signing key \"${key.kid}\" does not match declared algorithm \"${declaredKey.alg}\"`\n );\n }\n if (key.adcp_use !== 'request-signing') {\n throw new Error(`functional request signing key \"${key.kid}\" must have adcp_use=\"request-signing\"`);\n }\n if (contract.stateful_vector_contract.revocation.pre_revoked_keyid === key.kid) {\n throw new Error(`functional request signing key \"${key.kid}\" is the contract's pre-revoked key`);\n }\n\n const privateKey: AdcpPrivateJsonWebKey = {\n kid: key.kid,\n kty: key.kty,\n ...(key.crv && { crv: key.crv }),\n ...(key.alg && { alg: key.alg }),\n ...(key.use && { use: key.use }),\n key_ops: ['sign'],\n ...(key.adcp_use && { adcp_use: key.adcp_use }),\n ...(key.x && { x: key.x }),\n ...(key.y && { y: key.y }),\n d: key.private_d,\n };\n const signing: AgentRequestSigningConfig = {\n kind: 'inline',\n kid: key.kid,\n alg,\n private_key: privateKey,\n agent_url: dispatch.signer_agent_url,\n sign_supported: dispatch.operation_selection.sign_supported_for,\n };\n return { ...options, functional_request_signing: signing };\n}\n"],"mappings":"AAEA,SAAS,wBAAwB,eAAe;AAChD,SAAS,wCAAwC;AAgB1C,SAAS,8BACd,SACA,cAA6C,CAAC,GAC3C;AACH,MAAI,QAAQ,YAAY,QAAQ,QAAQ,oBAAoB,KAAM,QAAO;AAEzE,QAAM,WAAW,iCAAiC,WAAW;AAC7D,QAAM,WAAW,UAAU;AAG3B,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,SAAS,mBAAmB,WAAW;AACzC,UAAM,IAAI;AAAA,MACR,qGAAqG,SAAS,cAAc;AAAA,IAC9H;AAAA,EACF;AACA,MAAI,CAAC,SAAS,oBAAoB,mBAAmB;AACnD,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AACA,MAAI,CAAC,SAAS,oBAAoB,oBAAoB;AACpD,UAAM,IAAI,MAAM,oEAAoE;AAAA,EACtF;AACA,MACE,SAAS,8BAA8B,WAAW,KAClD,SAAS,8BAA8B,CAAC,MAAM,yBAC9C;AACA,UAAM,IAAI,MAAM,iGAAiG;AAAA,EACnH;AACA,MAAI,CAAC,SAAS,2BAA2B,CAAC,SAAS,8BAA8B;AAC/E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,kBAAkB,QAAQ;AAChC,MAAI,iBAAiB;AACnB,QAAI,gBAAgB,aAAa,SAAS,uBAAuB,GAAG;AAClE,YAAM,IAAI,MAAM,4FAA4F;AAAA,IAC9G;AACA,QAAI,gBAAgB,mBAAmB,KAAM,QAAO;AACpD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,4BAA4B,EAAE,GAAG,iBAAiB,gBAAgB,KAAK;AAAA,IACzE;AAAA,EACF;AAEA,QAAM,cAAc,SAAS,oBAAoB,KAAK,WAAS,MAAM,UAAU,SAAS,aAAa;AACrG,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI;AAAA,MACR,mCAAmC,SAAS,aAAa;AAAA,IAC3D;AAAA,EACF;AACA,QAAM,MAAM,QAAQ,uBAAuB,WAAW,GAAG,SAAS,aAAa;AAC/E,QAAM,MAAM,IAAI,QAAQ,YAAY,YAAY,IAAI,QAAQ,UAAU,sBAAsB;AAC5F,MAAI,CAAC,OAAO,QAAQ,YAAY,KAAK;AACnC,UAAM,IAAI;AAAA,MACR,mCAAmC,IAAI,GAAG,wCAAwC,YAAY,GAAG;AAAA,IACnG;AAAA,EACF;AACA,MAAI,IAAI,aAAa,mBAAmB;AACtC,UAAM,IAAI,MAAM,mCAAmC,IAAI,GAAG,wCAAwC;AAAA,EACpG;AACA,MAAI,SAAS,yBAAyB,WAAW,sBAAsB,IAAI,KAAK;AAC9E,UAAM,IAAI,MAAM,mCAAmC,IAAI,GAAG,qCAAqC;AAAA,EACjG;AAEA,QAAM,aAAoC;AAAA,IACxC,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,IACT,GAAI,IAAI,OAAO,EAAE,KAAK,IAAI,IAAI;AAAA,IAC9B,GAAI,IAAI,OAAO,EAAE,KAAK,IAAI,IAAI;AAAA,IAC9B,GAAI,IAAI,OAAO,EAAE,KAAK,IAAI,IAAI;AAAA,IAC9B,SAAS,CAAC,MAAM;AAAA,IAChB,GAAI,IAAI,YAAY,EAAE,UAAU,IAAI,SAAS;AAAA,IAC7C,GAAI,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE;AAAA,IACxB,GAAI,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE;AAAA,IACxB,GAAG,IAAI;AAAA,EACT;AACA,QAAM,UAAqC;AAAA,IACzC,MAAM;AAAA,IACN,KAAK,IAAI;AAAA,IACT;AAAA,IACA,aAAa;AAAA,IACb,WAAW,SAAS;AAAA,IACpB,gBAAgB,SAAS,oBAAoB;AAAA,EAC/C;AACA,SAAO,EAAE,GAAG,SAAS,4BAA4B,QAAQ;AAC3D;","names":[]}
@@ -18,11 +18,26 @@ export interface RateAbuseContract {
18
18
  production_min_per_keyid_cap_requests: number;
19
19
  window_seconds: number;
20
20
  }
21
+ export interface FunctionalDispatchContract {
22
+ signing_keyid: string;
23
+ signer_agent_url: string;
24
+ operation_selection: {
25
+ capability_path: 'request_signing';
26
+ sign_required_for: boolean;
27
+ sign_supported_for: boolean;
28
+ };
29
+ content_digest_policy_source: 'request_signing.covers_content_digest';
30
+ preserve_transport_auth: boolean;
31
+ fresh_signature_per_dispatch: boolean;
32
+ bootstrap_operations_unsigned: string[];
33
+ unavailable_behavior: 'not_applicable';
34
+ }
21
35
  export interface SignedRequestsRunnerContract {
22
36
  id: string;
23
37
  endpoint_scope: 'sandbox' | string;
24
38
  harness_mode: 'black_box' | 'white_box';
25
39
  runner_signing_keys: RunnerSigningKey[];
40
+ functional_dispatch?: FunctionalDispatchContract;
26
41
  stateful_vector_contract: {
27
42
  replay_window: ReplayWindowContract;
28
43
  revocation: RevocationContract;
@@ -18,11 +18,26 @@ export interface RateAbuseContract {
18
18
  production_min_per_keyid_cap_requests: number;
19
19
  window_seconds: number;
20
20
  }
21
+ export interface FunctionalDispatchContract {
22
+ signing_keyid: string;
23
+ signer_agent_url: string;
24
+ operation_selection: {
25
+ capability_path: 'request_signing';
26
+ sign_required_for: boolean;
27
+ sign_supported_for: boolean;
28
+ };
29
+ content_digest_policy_source: 'request_signing.covers_content_digest';
30
+ preserve_transport_auth: boolean;
31
+ fresh_signature_per_dispatch: boolean;
32
+ bootstrap_operations_unsigned: string[];
33
+ unavailable_behavior: 'not_applicable';
34
+ }
21
35
  export interface SignedRequestsRunnerContract {
22
36
  id: string;
23
37
  endpoint_scope: 'sandbox' | string;
24
38
  harness_mode: 'black_box' | 'white_box';
25
39
  runner_signing_keys: RunnerSigningKey[];
40
+ functional_dispatch?: FunctionalDispatchContract;
26
41
  stateful_vector_contract: {
27
42
  replay_window: ReplayWindowContract;
28
43
  revocation: RevocationContract;
@@ -1 +1 @@
1
- {"version":3,"file":"test-kit.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,SAAS,GAAG,mBAAmB,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,gBAAgB,CAAC;IACrC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC,EAAE,MAAM,CAAC;IAC9C,qCAAqC,EAAE,MAAM,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC,YAAY,EAAE,WAAW,GAAG,WAAW,CAAC;IACxC,mBAAmB,EAAE,gBAAgB,EAAE,CAAC;IACxC,wBAAwB,EAAE;QACxB,aAAa,EAAE,oBAAoB,CAAC;QACpC,UAAU,EAAE,kBAAkB,CAAC;QAC/B,UAAU,EAAE,iBAAiB,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,kBAAuB,GAC/B,4BAA4B,GAAG,SAAS,CAY1C"}
1
+ {"version":3,"file":"test-kit.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,SAAS,GAAG,mBAAmB,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,gBAAgB,CAAC;IACrC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC,EAAE,MAAM,CAAC;IAC9C,qCAAqC,EAAE,MAAM,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE;QACnB,eAAe,EAAE,iBAAiB,CAAC;QACnC,iBAAiB,EAAE,OAAO,CAAC;QAC3B,kBAAkB,EAAE,OAAO,CAAC;KAC7B,CAAC;IACF,4BAA4B,EAAE,uCAAuC,CAAC;IACtE,uBAAuB,EAAE,OAAO,CAAC;IACjC,4BAA4B,EAAE,OAAO,CAAC;IACtC,6BAA6B,EAAE,MAAM,EAAE,CAAC;IACxC,oBAAoB,EAAE,gBAAgB,CAAC;CACxC;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC,YAAY,EAAE,WAAW,GAAG,WAAW,CAAC;IACxC,mBAAmB,EAAE,gBAAgB,EAAE,CAAC;IACxC,mBAAmB,CAAC,EAAE,0BAA0B,CAAC;IACjD,wBAAwB,EAAE;QACxB,aAAa,EAAE,oBAAoB,CAAC;QACpC,UAAU,EAAE,kBAAkB,CAAC;QAC/B,UAAU,EAAE,iBAAiB,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,kBAAuB,GAC/B,4BAA4B,GAAG,SAAS,CAc1C"}
@@ -30,14 +30,62 @@ function loadSignedRequestsRunnerContract(options = {}) {
30
30
  const path = (0, import_path.join)(cacheDir, "test-kits", "signed-requests-runner.yaml");
31
31
  if (!(0, import_fs.existsSync)(path)) return void 0;
32
32
  const raw = (0, import_yaml.parse)((0, import_fs.readFileSync)(path, "utf-8"));
33
+ const functionalDispatch = parseFunctionalDispatch(raw.functional_dispatch);
33
34
  return {
34
35
  id: assertString(raw.id, "id"),
35
36
  endpoint_scope: assertString(raw.endpoint_scope, "endpoint_scope"),
36
37
  harness_mode: parseHarnessMode(raw.harness_mode),
37
38
  runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),
39
+ ...functionalDispatch && { functional_dispatch: functionalDispatch },
38
40
  stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract)
39
41
  };
40
42
  }
43
+ function parseFunctionalDispatch(raw) {
44
+ if (raw === void 0) return void 0;
45
+ const r = asObject(raw, "functional_dispatch");
46
+ const selection = asObject(r.operation_selection, "functional_dispatch.operation_selection");
47
+ const capabilityPath = assertString(
48
+ selection.capability_path,
49
+ "functional_dispatch.operation_selection.capability_path"
50
+ );
51
+ if (capabilityPath !== "request_signing") {
52
+ throw new Error('functional_dispatch.operation_selection.capability_path must be "request_signing"');
53
+ }
54
+ const digestSource = assertString(r.content_digest_policy_source, "functional_dispatch.content_digest_policy_source");
55
+ if (digestSource !== "request_signing.covers_content_digest") {
56
+ throw new Error('functional_dispatch.content_digest_policy_source must be "request_signing.covers_content_digest"');
57
+ }
58
+ const unavailable = assertString(r.unavailable_behavior, "functional_dispatch.unavailable_behavior");
59
+ if (unavailable !== "not_applicable") {
60
+ throw new Error('functional_dispatch.unavailable_behavior must be "not_applicable"');
61
+ }
62
+ return {
63
+ signing_keyid: assertString(r.signing_keyid, "functional_dispatch.signing_keyid"),
64
+ signer_agent_url: assertString(r.signer_agent_url, "functional_dispatch.signer_agent_url"),
65
+ operation_selection: {
66
+ capability_path: "request_signing",
67
+ sign_required_for: assertBoolean(
68
+ selection.sign_required_for,
69
+ "functional_dispatch.operation_selection.sign_required_for"
70
+ ),
71
+ sign_supported_for: assertBoolean(
72
+ selection.sign_supported_for,
73
+ "functional_dispatch.operation_selection.sign_supported_for"
74
+ )
75
+ },
76
+ content_digest_policy_source: "request_signing.covers_content_digest",
77
+ preserve_transport_auth: assertBoolean(r.preserve_transport_auth, "functional_dispatch.preserve_transport_auth"),
78
+ fresh_signature_per_dispatch: assertBoolean(
79
+ r.fresh_signature_per_dispatch,
80
+ "functional_dispatch.fresh_signature_per_dispatch"
81
+ ),
82
+ bootstrap_operations_unsigned: assertStringArray(
83
+ r.bootstrap_operations_unsigned,
84
+ "functional_dispatch.bootstrap_operations_unsigned"
85
+ ),
86
+ unavailable_behavior: "not_applicable"
87
+ };
88
+ }
41
89
  function parseHarnessMode(raw) {
42
90
  const s = assertString(raw, "harness_mode");
43
91
  if (s !== "black_box" && s !== "white_box") {
@@ -114,6 +162,16 @@ function assertNumber(v, where) {
114
162
  if (typeof v !== "number") throw new Error(`${where} must be number`);
115
163
  return v;
116
164
  }
165
+ function assertBoolean(v, where) {
166
+ if (typeof v !== "boolean") throw new Error(`${where} must be boolean`);
167
+ return v;
168
+ }
169
+ function assertStringArray(v, where) {
170
+ if (!Array.isArray(v) || v.some((item) => typeof item !== "string")) {
171
+ throw new Error(`${where} must be string[]`);
172
+ }
173
+ return v;
174
+ }
117
175
  // Annotate the CommonJS export names for ESM import in node:
118
176
  0 && (module.exports = {
119
177
  loadSignedRequestsRunnerContract
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from '../compliance';\n\nexport interface RunnerSigningKey {\n keyid: string;\n alg: 'ed25519' | 'ecdsa-p256-sha256';\n}\n\nexport interface ReplayWindowContract {\n vector_id: string;\n black_box_behavior: 'repeat_request';\n max_interval_seconds: number;\n min_replay_ttl_seconds: number;\n}\n\nexport interface RevocationContract {\n vector_id: string;\n pre_revoked_keyid: string;\n}\n\nexport interface RateAbuseContract {\n vector_id: string;\n grading_target_per_keyid_cap_requests: number;\n production_min_per_keyid_cap_requests: number;\n window_seconds: number;\n}\n\nexport interface SignedRequestsRunnerContract {\n id: string;\n endpoint_scope: 'sandbox' | string;\n harness_mode: 'black_box' | 'white_box';\n runner_signing_keys: RunnerSigningKey[];\n stateful_vector_contract: {\n replay_window: ReplayWindowContract;\n revocation: RevocationContract;\n rate_abuse: RateAbuseContract;\n };\n}\n\nexport interface LoadTestKitOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Load and parse `test-kits/signed-requests-runner.yaml` from the compliance\n * cache. Returns undefined when the file is absent (upstream pre-adcp#2353\n * caches, or a sync in progress) — callers must decide how to degrade.\n */\nexport function loadSignedRequestsRunnerContract(\n options: LoadTestKitOptions = {}\n): SignedRequestsRunnerContract | undefined {\n const cacheDir = getComplianceCacheDir(options);\n const path = join(cacheDir, 'test-kits', 'signed-requests-runner.yaml');\n if (!existsSync(path)) return undefined;\n const raw = parse(readFileSync(path, 'utf-8')) as Record<string, unknown>;\n return {\n id: assertString(raw.id, 'id'),\n endpoint_scope: assertString(raw.endpoint_scope, 'endpoint_scope'),\n harness_mode: parseHarnessMode(raw.harness_mode),\n runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),\n stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract),\n };\n}\n\nfunction parseHarnessMode(raw: unknown): 'black_box' | 'white_box' {\n const s = assertString(raw, 'harness_mode');\n if (s !== 'black_box' && s !== 'white_box') {\n throw new Error(`test-kit harness_mode must be \"black_box\" or \"white_box\", got \"${s}\"`);\n }\n return s;\n}\n\nfunction parseSigningKeys(raw: unknown): RunnerSigningKey[] {\n if (!Array.isArray(raw)) throw new Error('runner_signing_keys must be an array');\n return raw.map((entry, i) => {\n const r = entry as Record<string, unknown>;\n const alg = assertString(r.alg, `runner_signing_keys[${i}].alg`);\n if (alg !== 'ed25519' && alg !== 'ecdsa-p256-sha256') {\n throw new Error(`runner_signing_keys[${i}].alg: unsupported \"${alg}\"`);\n }\n return { keyid: assertString(r.keyid, `runner_signing_keys[${i}].keyid`), alg };\n });\n}\n\nfunction parseStatefulContracts(raw: unknown): SignedRequestsRunnerContract['stateful_vector_contract'] {\n if (!raw || typeof raw !== 'object') {\n throw new Error('stateful_vector_contract block missing');\n }\n const r = raw as Record<string, unknown>;\n return {\n replay_window: parseReplay(r.replay_window),\n revocation: parseRevocation(r.revocation),\n rate_abuse: parseRateAbuse(r.rate_abuse),\n };\n}\n\nfunction parseReplay(raw: unknown): ReplayWindowContract {\n const r = asObject(raw, 'stateful_vector_contract.replay_window');\n const behavior = assertString(r.black_box_behavior, 'replay_window.black_box_behavior');\n if (behavior !== 'repeat_request') {\n throw new Error(`replay_window.black_box_behavior must be \"repeat_request\", got \"${behavior}\"`);\n }\n return {\n vector_id: assertString(r.vector_id, 'replay_window.vector_id'),\n black_box_behavior: 'repeat_request',\n max_interval_seconds: assertNumber(r.max_interval_seconds, 'replay_window.max_interval_seconds'),\n min_replay_ttl_seconds: assertNumber(r.min_replay_ttl_seconds, 'replay_window.min_replay_ttl_seconds'),\n };\n}\n\nfunction parseRevocation(raw: unknown): RevocationContract {\n const r = asObject(raw, 'stateful_vector_contract.revocation');\n return {\n vector_id: assertString(r.vector_id, 'revocation.vector_id'),\n pre_revoked_keyid: assertString(r.pre_revoked_keyid, 'revocation.pre_revoked_keyid'),\n };\n}\n\nfunction parseRateAbuse(raw: unknown): RateAbuseContract {\n const r = asObject(raw, 'stateful_vector_contract.rate_abuse');\n return {\n vector_id: assertString(r.vector_id, 'rate_abuse.vector_id'),\n grading_target_per_keyid_cap_requests: assertNumber(\n r.grading_target_per_keyid_cap_requests,\n 'rate_abuse.grading_target_per_keyid_cap_requests'\n ),\n production_min_per_keyid_cap_requests: assertNumber(\n r.production_min_per_keyid_cap_requests,\n 'rate_abuse.production_min_per_keyid_cap_requests'\n ),\n window_seconds: assertNumber(r.window_seconds, 'rate_abuse.window_seconds'),\n };\n}\n\nfunction asObject(raw: unknown, where: string): Record<string, unknown> {\n if (!raw || typeof raw !== 'object') throw new Error(`${where} missing or not an object`);\n return raw as Record<string, unknown>;\n}\n\nfunction assertString(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction assertNumber(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from '../compliance';\n\nexport interface RunnerSigningKey {\n keyid: string;\n alg: 'ed25519' | 'ecdsa-p256-sha256';\n}\n\nexport interface ReplayWindowContract {\n vector_id: string;\n black_box_behavior: 'repeat_request';\n max_interval_seconds: number;\n min_replay_ttl_seconds: number;\n}\n\nexport interface RevocationContract {\n vector_id: string;\n pre_revoked_keyid: string;\n}\n\nexport interface RateAbuseContract {\n vector_id: string;\n grading_target_per_keyid_cap_requests: number;\n production_min_per_keyid_cap_requests: number;\n window_seconds: number;\n}\n\nexport interface FunctionalDispatchContract {\n signing_keyid: string;\n signer_agent_url: string;\n operation_selection: {\n capability_path: 'request_signing';\n sign_required_for: boolean;\n sign_supported_for: boolean;\n };\n content_digest_policy_source: 'request_signing.covers_content_digest';\n preserve_transport_auth: boolean;\n fresh_signature_per_dispatch: boolean;\n bootstrap_operations_unsigned: string[];\n unavailable_behavior: 'not_applicable';\n}\n\nexport interface SignedRequestsRunnerContract {\n id: string;\n endpoint_scope: 'sandbox' | string;\n harness_mode: 'black_box' | 'white_box';\n runner_signing_keys: RunnerSigningKey[];\n functional_dispatch?: FunctionalDispatchContract;\n stateful_vector_contract: {\n replay_window: ReplayWindowContract;\n revocation: RevocationContract;\n rate_abuse: RateAbuseContract;\n };\n}\n\nexport interface LoadTestKitOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Load and parse `test-kits/signed-requests-runner.yaml` from the compliance\n * cache. Returns undefined when the file is absent (upstream pre-adcp#2353\n * caches, or a sync in progress) — callers must decide how to degrade.\n */\nexport function loadSignedRequestsRunnerContract(\n options: LoadTestKitOptions = {}\n): SignedRequestsRunnerContract | undefined {\n const cacheDir = getComplianceCacheDir(options);\n const path = join(cacheDir, 'test-kits', 'signed-requests-runner.yaml');\n if (!existsSync(path)) return undefined;\n const raw = parse(readFileSync(path, 'utf-8')) as Record<string, unknown>;\n const functionalDispatch = parseFunctionalDispatch(raw.functional_dispatch);\n return {\n id: assertString(raw.id, 'id'),\n endpoint_scope: assertString(raw.endpoint_scope, 'endpoint_scope'),\n harness_mode: parseHarnessMode(raw.harness_mode),\n runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),\n ...(functionalDispatch && { functional_dispatch: functionalDispatch }),\n stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract),\n };\n}\n\nfunction parseFunctionalDispatch(raw: unknown): FunctionalDispatchContract | undefined {\n if (raw === undefined) return undefined;\n const r = asObject(raw, 'functional_dispatch');\n const selection = asObject(r.operation_selection, 'functional_dispatch.operation_selection');\n const capabilityPath = assertString(\n selection.capability_path,\n 'functional_dispatch.operation_selection.capability_path'\n );\n if (capabilityPath !== 'request_signing') {\n throw new Error('functional_dispatch.operation_selection.capability_path must be \"request_signing\"');\n }\n const digestSource = assertString(r.content_digest_policy_source, 'functional_dispatch.content_digest_policy_source');\n if (digestSource !== 'request_signing.covers_content_digest') {\n throw new Error('functional_dispatch.content_digest_policy_source must be \"request_signing.covers_content_digest\"');\n }\n const unavailable = assertString(r.unavailable_behavior, 'functional_dispatch.unavailable_behavior');\n if (unavailable !== 'not_applicable') {\n throw new Error('functional_dispatch.unavailable_behavior must be \"not_applicable\"');\n }\n return {\n signing_keyid: assertString(r.signing_keyid, 'functional_dispatch.signing_keyid'),\n signer_agent_url: assertString(r.signer_agent_url, 'functional_dispatch.signer_agent_url'),\n operation_selection: {\n capability_path: 'request_signing',\n sign_required_for: assertBoolean(\n selection.sign_required_for,\n 'functional_dispatch.operation_selection.sign_required_for'\n ),\n sign_supported_for: assertBoolean(\n selection.sign_supported_for,\n 'functional_dispatch.operation_selection.sign_supported_for'\n ),\n },\n content_digest_policy_source: 'request_signing.covers_content_digest',\n preserve_transport_auth: assertBoolean(r.preserve_transport_auth, 'functional_dispatch.preserve_transport_auth'),\n fresh_signature_per_dispatch: assertBoolean(\n r.fresh_signature_per_dispatch,\n 'functional_dispatch.fresh_signature_per_dispatch'\n ),\n bootstrap_operations_unsigned: assertStringArray(\n r.bootstrap_operations_unsigned,\n 'functional_dispatch.bootstrap_operations_unsigned'\n ),\n unavailable_behavior: 'not_applicable',\n };\n}\n\nfunction parseHarnessMode(raw: unknown): 'black_box' | 'white_box' {\n const s = assertString(raw, 'harness_mode');\n if (s !== 'black_box' && s !== 'white_box') {\n throw new Error(`test-kit harness_mode must be \"black_box\" or \"white_box\", got \"${s}\"`);\n }\n return s;\n}\n\nfunction parseSigningKeys(raw: unknown): RunnerSigningKey[] {\n if (!Array.isArray(raw)) throw new Error('runner_signing_keys must be an array');\n return raw.map((entry, i) => {\n const r = entry as Record<string, unknown>;\n const alg = assertString(r.alg, `runner_signing_keys[${i}].alg`);\n if (alg !== 'ed25519' && alg !== 'ecdsa-p256-sha256') {\n throw new Error(`runner_signing_keys[${i}].alg: unsupported \"${alg}\"`);\n }\n return { keyid: assertString(r.keyid, `runner_signing_keys[${i}].keyid`), alg };\n });\n}\n\nfunction parseStatefulContracts(raw: unknown): SignedRequestsRunnerContract['stateful_vector_contract'] {\n if (!raw || typeof raw !== 'object') {\n throw new Error('stateful_vector_contract block missing');\n }\n const r = raw as Record<string, unknown>;\n return {\n replay_window: parseReplay(r.replay_window),\n revocation: parseRevocation(r.revocation),\n rate_abuse: parseRateAbuse(r.rate_abuse),\n };\n}\n\nfunction parseReplay(raw: unknown): ReplayWindowContract {\n const r = asObject(raw, 'stateful_vector_contract.replay_window');\n const behavior = assertString(r.black_box_behavior, 'replay_window.black_box_behavior');\n if (behavior !== 'repeat_request') {\n throw new Error(`replay_window.black_box_behavior must be \"repeat_request\", got \"${behavior}\"`);\n }\n return {\n vector_id: assertString(r.vector_id, 'replay_window.vector_id'),\n black_box_behavior: 'repeat_request',\n max_interval_seconds: assertNumber(r.max_interval_seconds, 'replay_window.max_interval_seconds'),\n min_replay_ttl_seconds: assertNumber(r.min_replay_ttl_seconds, 'replay_window.min_replay_ttl_seconds'),\n };\n}\n\nfunction parseRevocation(raw: unknown): RevocationContract {\n const r = asObject(raw, 'stateful_vector_contract.revocation');\n return {\n vector_id: assertString(r.vector_id, 'revocation.vector_id'),\n pre_revoked_keyid: assertString(r.pre_revoked_keyid, 'revocation.pre_revoked_keyid'),\n };\n}\n\nfunction parseRateAbuse(raw: unknown): RateAbuseContract {\n const r = asObject(raw, 'stateful_vector_contract.rate_abuse');\n return {\n vector_id: assertString(r.vector_id, 'rate_abuse.vector_id'),\n grading_target_per_keyid_cap_requests: assertNumber(\n r.grading_target_per_keyid_cap_requests,\n 'rate_abuse.grading_target_per_keyid_cap_requests'\n ),\n production_min_per_keyid_cap_requests: assertNumber(\n r.production_min_per_keyid_cap_requests,\n 'rate_abuse.production_min_per_keyid_cap_requests'\n ),\n window_seconds: assertNumber(r.window_seconds, 'rate_abuse.window_seconds'),\n };\n}\n\nfunction asObject(raw: unknown, where: string): Record<string, unknown> {\n if (!raw || typeof raw !== 'object') throw new Error(`${where} missing or not an object`);\n return raw as Record<string, unknown>;\n}\n\nfunction assertString(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction assertNumber(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n\nfunction assertBoolean(v: unknown, where: string): boolean {\n if (typeof v !== 'boolean') throw new Error(`${where} must be boolean`);\n return v;\n}\n\nfunction assertStringArray(v: unknown, where: string): string[] {\n if (!Array.isArray(v) || v.some(item => typeof item !== 'string')) {\n throw new Error(`${where} must be string[]`);\n }\n return v;\n}\n"],"mappings":"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","names":[]}
@@ -7,14 +7,62 @@ function loadSignedRequestsRunnerContract(options = {}) {
7
7
  const path = join(cacheDir, "test-kits", "signed-requests-runner.yaml");
8
8
  if (!existsSync(path)) return void 0;
9
9
  const raw = parse(readFileSync(path, "utf-8"));
10
+ const functionalDispatch = parseFunctionalDispatch(raw.functional_dispatch);
10
11
  return {
11
12
  id: assertString(raw.id, "id"),
12
13
  endpoint_scope: assertString(raw.endpoint_scope, "endpoint_scope"),
13
14
  harness_mode: parseHarnessMode(raw.harness_mode),
14
15
  runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),
16
+ ...functionalDispatch && { functional_dispatch: functionalDispatch },
15
17
  stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract)
16
18
  };
17
19
  }
20
+ function parseFunctionalDispatch(raw) {
21
+ if (raw === void 0) return void 0;
22
+ const r = asObject(raw, "functional_dispatch");
23
+ const selection = asObject(r.operation_selection, "functional_dispatch.operation_selection");
24
+ const capabilityPath = assertString(
25
+ selection.capability_path,
26
+ "functional_dispatch.operation_selection.capability_path"
27
+ );
28
+ if (capabilityPath !== "request_signing") {
29
+ throw new Error('functional_dispatch.operation_selection.capability_path must be "request_signing"');
30
+ }
31
+ const digestSource = assertString(r.content_digest_policy_source, "functional_dispatch.content_digest_policy_source");
32
+ if (digestSource !== "request_signing.covers_content_digest") {
33
+ throw new Error('functional_dispatch.content_digest_policy_source must be "request_signing.covers_content_digest"');
34
+ }
35
+ const unavailable = assertString(r.unavailable_behavior, "functional_dispatch.unavailable_behavior");
36
+ if (unavailable !== "not_applicable") {
37
+ throw new Error('functional_dispatch.unavailable_behavior must be "not_applicable"');
38
+ }
39
+ return {
40
+ signing_keyid: assertString(r.signing_keyid, "functional_dispatch.signing_keyid"),
41
+ signer_agent_url: assertString(r.signer_agent_url, "functional_dispatch.signer_agent_url"),
42
+ operation_selection: {
43
+ capability_path: "request_signing",
44
+ sign_required_for: assertBoolean(
45
+ selection.sign_required_for,
46
+ "functional_dispatch.operation_selection.sign_required_for"
47
+ ),
48
+ sign_supported_for: assertBoolean(
49
+ selection.sign_supported_for,
50
+ "functional_dispatch.operation_selection.sign_supported_for"
51
+ )
52
+ },
53
+ content_digest_policy_source: "request_signing.covers_content_digest",
54
+ preserve_transport_auth: assertBoolean(r.preserve_transport_auth, "functional_dispatch.preserve_transport_auth"),
55
+ fresh_signature_per_dispatch: assertBoolean(
56
+ r.fresh_signature_per_dispatch,
57
+ "functional_dispatch.fresh_signature_per_dispatch"
58
+ ),
59
+ bootstrap_operations_unsigned: assertStringArray(
60
+ r.bootstrap_operations_unsigned,
61
+ "functional_dispatch.bootstrap_operations_unsigned"
62
+ ),
63
+ unavailable_behavior: "not_applicable"
64
+ };
65
+ }
18
66
  function parseHarnessMode(raw) {
19
67
  const s = assertString(raw, "harness_mode");
20
68
  if (s !== "black_box" && s !== "white_box") {
@@ -91,6 +139,16 @@ function assertNumber(v, where) {
91
139
  if (typeof v !== "number") throw new Error(`${where} must be number`);
92
140
  return v;
93
141
  }
142
+ function assertBoolean(v, where) {
143
+ if (typeof v !== "boolean") throw new Error(`${where} must be boolean`);
144
+ return v;
145
+ }
146
+ function assertStringArray(v, where) {
147
+ if (!Array.isArray(v) || v.some((item) => typeof item !== "string")) {
148
+ throw new Error(`${where} must be string[]`);
149
+ }
150
+ return v;
151
+ }
94
152
  export {
95
153
  loadSignedRequestsRunnerContract
96
154
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from '../compliance';\n\nexport interface RunnerSigningKey {\n keyid: string;\n alg: 'ed25519' | 'ecdsa-p256-sha256';\n}\n\nexport interface ReplayWindowContract {\n vector_id: string;\n black_box_behavior: 'repeat_request';\n max_interval_seconds: number;\n min_replay_ttl_seconds: number;\n}\n\nexport interface RevocationContract {\n vector_id: string;\n pre_revoked_keyid: string;\n}\n\nexport interface RateAbuseContract {\n vector_id: string;\n grading_target_per_keyid_cap_requests: number;\n production_min_per_keyid_cap_requests: number;\n window_seconds: number;\n}\n\nexport interface SignedRequestsRunnerContract {\n id: string;\n endpoint_scope: 'sandbox' | string;\n harness_mode: 'black_box' | 'white_box';\n runner_signing_keys: RunnerSigningKey[];\n stateful_vector_contract: {\n replay_window: ReplayWindowContract;\n revocation: RevocationContract;\n rate_abuse: RateAbuseContract;\n };\n}\n\nexport interface LoadTestKitOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Load and parse `test-kits/signed-requests-runner.yaml` from the compliance\n * cache. Returns undefined when the file is absent (upstream pre-adcp#2353\n * caches, or a sync in progress) — callers must decide how to degrade.\n */\nexport function loadSignedRequestsRunnerContract(\n options: LoadTestKitOptions = {}\n): SignedRequestsRunnerContract | undefined {\n const cacheDir = getComplianceCacheDir(options);\n const path = join(cacheDir, 'test-kits', 'signed-requests-runner.yaml');\n if (!existsSync(path)) return undefined;\n const raw = parse(readFileSync(path, 'utf-8')) as Record<string, unknown>;\n return {\n id: assertString(raw.id, 'id'),\n endpoint_scope: assertString(raw.endpoint_scope, 'endpoint_scope'),\n harness_mode: parseHarnessMode(raw.harness_mode),\n runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),\n stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract),\n };\n}\n\nfunction parseHarnessMode(raw: unknown): 'black_box' | 'white_box' {\n const s = assertString(raw, 'harness_mode');\n if (s !== 'black_box' && s !== 'white_box') {\n throw new Error(`test-kit harness_mode must be \"black_box\" or \"white_box\", got \"${s}\"`);\n }\n return s;\n}\n\nfunction parseSigningKeys(raw: unknown): RunnerSigningKey[] {\n if (!Array.isArray(raw)) throw new Error('runner_signing_keys must be an array');\n return raw.map((entry, i) => {\n const r = entry as Record<string, unknown>;\n const alg = assertString(r.alg, `runner_signing_keys[${i}].alg`);\n if (alg !== 'ed25519' && alg !== 'ecdsa-p256-sha256') {\n throw new Error(`runner_signing_keys[${i}].alg: unsupported \"${alg}\"`);\n }\n return { keyid: assertString(r.keyid, `runner_signing_keys[${i}].keyid`), alg };\n });\n}\n\nfunction parseStatefulContracts(raw: unknown): SignedRequestsRunnerContract['stateful_vector_contract'] {\n if (!raw || typeof raw !== 'object') {\n throw new Error('stateful_vector_contract block missing');\n }\n const r = raw as Record<string, unknown>;\n return {\n replay_window: parseReplay(r.replay_window),\n revocation: parseRevocation(r.revocation),\n rate_abuse: parseRateAbuse(r.rate_abuse),\n };\n}\n\nfunction parseReplay(raw: unknown): ReplayWindowContract {\n const r = asObject(raw, 'stateful_vector_contract.replay_window');\n const behavior = assertString(r.black_box_behavior, 'replay_window.black_box_behavior');\n if (behavior !== 'repeat_request') {\n throw new Error(`replay_window.black_box_behavior must be \"repeat_request\", got \"${behavior}\"`);\n }\n return {\n vector_id: assertString(r.vector_id, 'replay_window.vector_id'),\n black_box_behavior: 'repeat_request',\n max_interval_seconds: assertNumber(r.max_interval_seconds, 'replay_window.max_interval_seconds'),\n min_replay_ttl_seconds: assertNumber(r.min_replay_ttl_seconds, 'replay_window.min_replay_ttl_seconds'),\n };\n}\n\nfunction parseRevocation(raw: unknown): RevocationContract {\n const r = asObject(raw, 'stateful_vector_contract.revocation');\n return {\n vector_id: assertString(r.vector_id, 'revocation.vector_id'),\n pre_revoked_keyid: assertString(r.pre_revoked_keyid, 'revocation.pre_revoked_keyid'),\n };\n}\n\nfunction parseRateAbuse(raw: unknown): RateAbuseContract {\n const r = asObject(raw, 'stateful_vector_contract.rate_abuse');\n return {\n vector_id: assertString(r.vector_id, 'rate_abuse.vector_id'),\n grading_target_per_keyid_cap_requests: assertNumber(\n r.grading_target_per_keyid_cap_requests,\n 'rate_abuse.grading_target_per_keyid_cap_requests'\n ),\n production_min_per_keyid_cap_requests: assertNumber(\n r.production_min_per_keyid_cap_requests,\n 'rate_abuse.production_min_per_keyid_cap_requests'\n ),\n window_seconds: assertNumber(r.window_seconds, 'rate_abuse.window_seconds'),\n };\n}\n\nfunction asObject(raw: unknown, where: string): Record<string, unknown> {\n if (!raw || typeof raw !== 'object') throw new Error(`${where} missing or not an object`);\n return raw as Record<string, unknown>;\n}\n\nfunction assertString(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction assertNumber(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from '../compliance';\n\nexport interface RunnerSigningKey {\n keyid: string;\n alg: 'ed25519' | 'ecdsa-p256-sha256';\n}\n\nexport interface ReplayWindowContract {\n vector_id: string;\n black_box_behavior: 'repeat_request';\n max_interval_seconds: number;\n min_replay_ttl_seconds: number;\n}\n\nexport interface RevocationContract {\n vector_id: string;\n pre_revoked_keyid: string;\n}\n\nexport interface RateAbuseContract {\n vector_id: string;\n grading_target_per_keyid_cap_requests: number;\n production_min_per_keyid_cap_requests: number;\n window_seconds: number;\n}\n\nexport interface FunctionalDispatchContract {\n signing_keyid: string;\n signer_agent_url: string;\n operation_selection: {\n capability_path: 'request_signing';\n sign_required_for: boolean;\n sign_supported_for: boolean;\n };\n content_digest_policy_source: 'request_signing.covers_content_digest';\n preserve_transport_auth: boolean;\n fresh_signature_per_dispatch: boolean;\n bootstrap_operations_unsigned: string[];\n unavailable_behavior: 'not_applicable';\n}\n\nexport interface SignedRequestsRunnerContract {\n id: string;\n endpoint_scope: 'sandbox' | string;\n harness_mode: 'black_box' | 'white_box';\n runner_signing_keys: RunnerSigningKey[];\n functional_dispatch?: FunctionalDispatchContract;\n stateful_vector_contract: {\n replay_window: ReplayWindowContract;\n revocation: RevocationContract;\n rate_abuse: RateAbuseContract;\n };\n}\n\nexport interface LoadTestKitOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Load and parse `test-kits/signed-requests-runner.yaml` from the compliance\n * cache. Returns undefined when the file is absent (upstream pre-adcp#2353\n * caches, or a sync in progress) — callers must decide how to degrade.\n */\nexport function loadSignedRequestsRunnerContract(\n options: LoadTestKitOptions = {}\n): SignedRequestsRunnerContract | undefined {\n const cacheDir = getComplianceCacheDir(options);\n const path = join(cacheDir, 'test-kits', 'signed-requests-runner.yaml');\n if (!existsSync(path)) return undefined;\n const raw = parse(readFileSync(path, 'utf-8')) as Record<string, unknown>;\n const functionalDispatch = parseFunctionalDispatch(raw.functional_dispatch);\n return {\n id: assertString(raw.id, 'id'),\n endpoint_scope: assertString(raw.endpoint_scope, 'endpoint_scope'),\n harness_mode: parseHarnessMode(raw.harness_mode),\n runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),\n ...(functionalDispatch && { functional_dispatch: functionalDispatch }),\n stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract),\n };\n}\n\nfunction parseFunctionalDispatch(raw: unknown): FunctionalDispatchContract | undefined {\n if (raw === undefined) return undefined;\n const r = asObject(raw, 'functional_dispatch');\n const selection = asObject(r.operation_selection, 'functional_dispatch.operation_selection');\n const capabilityPath = assertString(\n selection.capability_path,\n 'functional_dispatch.operation_selection.capability_path'\n );\n if (capabilityPath !== 'request_signing') {\n throw new Error('functional_dispatch.operation_selection.capability_path must be \"request_signing\"');\n }\n const digestSource = assertString(r.content_digest_policy_source, 'functional_dispatch.content_digest_policy_source');\n if (digestSource !== 'request_signing.covers_content_digest') {\n throw new Error('functional_dispatch.content_digest_policy_source must be \"request_signing.covers_content_digest\"');\n }\n const unavailable = assertString(r.unavailable_behavior, 'functional_dispatch.unavailable_behavior');\n if (unavailable !== 'not_applicable') {\n throw new Error('functional_dispatch.unavailable_behavior must be \"not_applicable\"');\n }\n return {\n signing_keyid: assertString(r.signing_keyid, 'functional_dispatch.signing_keyid'),\n signer_agent_url: assertString(r.signer_agent_url, 'functional_dispatch.signer_agent_url'),\n operation_selection: {\n capability_path: 'request_signing',\n sign_required_for: assertBoolean(\n selection.sign_required_for,\n 'functional_dispatch.operation_selection.sign_required_for'\n ),\n sign_supported_for: assertBoolean(\n selection.sign_supported_for,\n 'functional_dispatch.operation_selection.sign_supported_for'\n ),\n },\n content_digest_policy_source: 'request_signing.covers_content_digest',\n preserve_transport_auth: assertBoolean(r.preserve_transport_auth, 'functional_dispatch.preserve_transport_auth'),\n fresh_signature_per_dispatch: assertBoolean(\n r.fresh_signature_per_dispatch,\n 'functional_dispatch.fresh_signature_per_dispatch'\n ),\n bootstrap_operations_unsigned: assertStringArray(\n r.bootstrap_operations_unsigned,\n 'functional_dispatch.bootstrap_operations_unsigned'\n ),\n unavailable_behavior: 'not_applicable',\n };\n}\n\nfunction parseHarnessMode(raw: unknown): 'black_box' | 'white_box' {\n const s = assertString(raw, 'harness_mode');\n if (s !== 'black_box' && s !== 'white_box') {\n throw new Error(`test-kit harness_mode must be \"black_box\" or \"white_box\", got \"${s}\"`);\n }\n return s;\n}\n\nfunction parseSigningKeys(raw: unknown): RunnerSigningKey[] {\n if (!Array.isArray(raw)) throw new Error('runner_signing_keys must be an array');\n return raw.map((entry, i) => {\n const r = entry as Record<string, unknown>;\n const alg = assertString(r.alg, `runner_signing_keys[${i}].alg`);\n if (alg !== 'ed25519' && alg !== 'ecdsa-p256-sha256') {\n throw new Error(`runner_signing_keys[${i}].alg: unsupported \"${alg}\"`);\n }\n return { keyid: assertString(r.keyid, `runner_signing_keys[${i}].keyid`), alg };\n });\n}\n\nfunction parseStatefulContracts(raw: unknown): SignedRequestsRunnerContract['stateful_vector_contract'] {\n if (!raw || typeof raw !== 'object') {\n throw new Error('stateful_vector_contract block missing');\n }\n const r = raw as Record<string, unknown>;\n return {\n replay_window: parseReplay(r.replay_window),\n revocation: parseRevocation(r.revocation),\n rate_abuse: parseRateAbuse(r.rate_abuse),\n };\n}\n\nfunction parseReplay(raw: unknown): ReplayWindowContract {\n const r = asObject(raw, 'stateful_vector_contract.replay_window');\n const behavior = assertString(r.black_box_behavior, 'replay_window.black_box_behavior');\n if (behavior !== 'repeat_request') {\n throw new Error(`replay_window.black_box_behavior must be \"repeat_request\", got \"${behavior}\"`);\n }\n return {\n vector_id: assertString(r.vector_id, 'replay_window.vector_id'),\n black_box_behavior: 'repeat_request',\n max_interval_seconds: assertNumber(r.max_interval_seconds, 'replay_window.max_interval_seconds'),\n min_replay_ttl_seconds: assertNumber(r.min_replay_ttl_seconds, 'replay_window.min_replay_ttl_seconds'),\n };\n}\n\nfunction parseRevocation(raw: unknown): RevocationContract {\n const r = asObject(raw, 'stateful_vector_contract.revocation');\n return {\n vector_id: assertString(r.vector_id, 'revocation.vector_id'),\n pre_revoked_keyid: assertString(r.pre_revoked_keyid, 'revocation.pre_revoked_keyid'),\n };\n}\n\nfunction parseRateAbuse(raw: unknown): RateAbuseContract {\n const r = asObject(raw, 'stateful_vector_contract.rate_abuse');\n return {\n vector_id: assertString(r.vector_id, 'rate_abuse.vector_id'),\n grading_target_per_keyid_cap_requests: assertNumber(\n r.grading_target_per_keyid_cap_requests,\n 'rate_abuse.grading_target_per_keyid_cap_requests'\n ),\n production_min_per_keyid_cap_requests: assertNumber(\n r.production_min_per_keyid_cap_requests,\n 'rate_abuse.production_min_per_keyid_cap_requests'\n ),\n window_seconds: assertNumber(r.window_seconds, 'rate_abuse.window_seconds'),\n };\n}\n\nfunction asObject(raw: unknown, where: string): Record<string, unknown> {\n if (!raw || typeof raw !== 'object') throw new Error(`${where} missing or not an object`);\n return raw as Record<string, unknown>;\n}\n\nfunction assertString(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction assertNumber(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n\nfunction assertBoolean(v: unknown, where: string): boolean {\n if (typeof v !== 'boolean') throw new Error(`${where} must be boolean`);\n return v;\n}\n\nfunction assertStringArray(v: unknown, where: string): string[] {\n if (!Array.isArray(v) || v.some(item => typeof item !== 'string')) {\n throw new Error(`${where} must be string[]`);\n }\n return v;\n}\n"],"mappings":"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","names":[]}
@@ -14,6 +14,8 @@ export interface LoadedVectors {
14
14
  sourceDir: string;
15
15
  }
16
16
  export declare function loadRequestSigningVectors(options?: LoadVectorsOptions): LoadedVectors;
17
+ /** Load only the shared signing keyset, without requiring the grader vectors. */
18
+ export declare function loadRequestSigningKeys(options?: LoadVectorsOptions): TestKeyset;
17
19
  /** Test-only: clear the memoization cache so a fresh cache path is reread. */
18
20
  export declare function __resetVectorCache(): void;
19
21
  export declare function findKey(keyset: TestKeyset, kid: string): TestKeypair;
@@ -14,6 +14,8 @@ export interface LoadedVectors {
14
14
  sourceDir: string;
15
15
  }
16
16
  export declare function loadRequestSigningVectors(options?: LoadVectorsOptions): LoadedVectors;
17
+ /** Load only the shared signing keyset, without requiring the grader vectors. */
18
+ export declare function loadRequestSigningKeys(options?: LoadVectorsOptions): TestKeyset;
17
19
  /** Test-only: clear the memoization cache so a fresh cache path is reread. */
18
20
  export declare function __resetVectorCache(): void;
19
21
  export declare function findKey(keyset: TestKeyset, kid: string): TestKeypair;
@@ -1 +1 @@
1
- {"version":3,"file":"vector-loader.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/vector-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAU,MAAM,SAAS,CAAC;AAE3G,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;QAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IACrF,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AA+BD,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa,CA6BzF;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAyLD,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAQpE"}
1
+ {"version":3,"file":"vector-loader.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/vector-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAU,MAAM,SAAS,CAAC;AAE3G,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;QAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IACrF,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AA+BD,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa,CA6BzF;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,kBAAuB,GAAG,UAAU,CAGnF;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAyLD,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAQpE"}