@agenticprimitives/agent-profile 1.0.0-alpha.21 → 1.0.0-alpha.23

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 (85) hide show
  1. package/README.md +54 -6
  2. package/dist/a2a/binding.d.ts +99 -0
  3. package/dist/a2a/binding.d.ts.map +1 -0
  4. package/dist/a2a/binding.js +142 -0
  5. package/dist/a2a/binding.js.map +1 -0
  6. package/dist/a2a/canonical.d.ts +31 -0
  7. package/dist/a2a/canonical.d.ts.map +1 -0
  8. package/dist/a2a/canonical.js +43 -0
  9. package/dist/a2a/canonical.js.map +1 -0
  10. package/dist/a2a/field-binding.d.ts +125 -0
  11. package/dist/a2a/field-binding.d.ts.map +1 -0
  12. package/dist/a2a/field-binding.js +242 -0
  13. package/dist/a2a/field-binding.js.map +1 -0
  14. package/dist/a2a/import.d.ts +39 -0
  15. package/dist/a2a/import.d.ts.map +1 -0
  16. package/dist/a2a/import.js +134 -0
  17. package/dist/a2a/import.js.map +1 -0
  18. package/dist/a2a/index.d.ts +13 -0
  19. package/dist/a2a/index.d.ts.map +1 -0
  20. package/dist/a2a/index.js +24 -0
  21. package/dist/a2a/index.js.map +1 -0
  22. package/dist/a2a/jws.d.ts +76 -0
  23. package/dist/a2a/jws.d.ts.map +1 -0
  24. package/dist/a2a/jws.js +186 -0
  25. package/dist/a2a/jws.js.map +1 -0
  26. package/dist/a2a/playbook-binding.d.ts +29 -0
  27. package/dist/a2a/playbook-binding.d.ts.map +1 -0
  28. package/dist/a2a/playbook-binding.js +65 -0
  29. package/dist/a2a/playbook-binding.js.map +1 -0
  30. package/dist/a2a/pointer.d.ts +13 -0
  31. package/dist/a2a/pointer.d.ts.map +1 -0
  32. package/dist/a2a/pointer.js +78 -0
  33. package/dist/a2a/pointer.js.map +1 -0
  34. package/dist/a2a/release.d.ts +77 -0
  35. package/dist/a2a/release.d.ts.map +1 -0
  36. package/dist/a2a/release.js +197 -0
  37. package/dist/a2a/release.js.map +1 -0
  38. package/dist/a2a/types.d.ts +312 -0
  39. package/dist/a2a/types.d.ts.map +1 -0
  40. package/dist/a2a/types.js +32 -0
  41. package/dist/a2a/types.js.map +1 -0
  42. package/dist/a2a/validation.d.ts +81 -0
  43. package/dist/a2a/validation.d.ts.map +1 -0
  44. package/dist/a2a/validation.js +477 -0
  45. package/dist/a2a/validation.js.map +1 -0
  46. package/dist/calls.d.ts +12 -0
  47. package/dist/calls.d.ts.map +1 -1
  48. package/dist/calls.js +16 -0
  49. package/dist/calls.js.map +1 -1
  50. package/dist/card.d.ts +12 -6
  51. package/dist/card.d.ts.map +1 -1
  52. package/dist/card.js +12 -6
  53. package/dist/card.js.map +1 -1
  54. package/dist/client.d.ts +4 -4
  55. package/dist/client.d.ts.map +1 -1
  56. package/dist/client.js +20 -2
  57. package/dist/client.js.map +1 -1
  58. package/dist/constants.d.ts +23 -1
  59. package/dist/constants.d.ts.map +1 -1
  60. package/dist/constants.js +30 -1
  61. package/dist/constants.js.map +1 -1
  62. package/dist/derived-type.d.ts +14 -0
  63. package/dist/derived-type.d.ts.map +1 -0
  64. package/dist/derived-type.js +56 -0
  65. package/dist/derived-type.js.map +1 -0
  66. package/dist/distribution.d.ts +32 -0
  67. package/dist/distribution.d.ts.map +1 -0
  68. package/dist/distribution.js +167 -0
  69. package/dist/distribution.js.map +1 -0
  70. package/dist/errors.d.ts +6 -0
  71. package/dist/errors.d.ts.map +1 -1
  72. package/dist/errors.js +11 -0
  73. package/dist/errors.js.map +1 -1
  74. package/dist/index.d.ts +7 -5
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +12 -5
  77. package/dist/index.js.map +1 -1
  78. package/dist/profile.d.ts +4 -4
  79. package/dist/profile.d.ts.map +1 -1
  80. package/dist/profile.js +12 -1
  81. package/dist/profile.js.map +1 -1
  82. package/dist/types.d.ts +104 -7
  83. package/dist/types.d.ts.map +1 -1
  84. package/package.json +13 -6
  85. package/spec.md +5 -1
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Standard A2A card signatures: detached JWS over the canonical card bytes (spec 347 §4.2).
3
+ *
4
+ * signing input = base64url(protected) "." base64url(canonicalCardBytes)
5
+ * protected = { alg: 'ES256' | 'EdDSA', kid: <RFC 7638 JWK thumbprint> }
6
+ *
7
+ * WebCrypto only (`globalThis.crypto.subtle`, Node ≥ 20 and workerd) — no `jose`. ES256 (P-256) is the
8
+ * Ring-0 default; EdDSA is used only when the runtime can do it (`supportsEdDSA()`), never required.
9
+ *
10
+ * Verification is FAIL-CLOSED (ADR-0013): no signatures, an unknown `kid`, an unsupported `alg`, a header
11
+ * that cannot be parsed, or any bad signature ⇒ `ok: false`. A non-AP A2A client verifies these signatures
12
+ * and never needs the Smart Agent binding (`binding.ts`).
13
+ */
14
+ import { jcsCanonicalize } from '@agenticprimitives/types';
15
+ import { canonicalCardBytes } from './canonical.js';
16
+ // ─── base64url ───────────────────────────────────────────────────────────────────────────────────────
17
+ export function base64UrlEncode(bytes) {
18
+ let bin = '';
19
+ for (let i = 0; i < bytes.length; i++)
20
+ bin += String.fromCharCode(bytes[i]);
21
+ return btoa(bin).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
22
+ }
23
+ export function base64UrlDecode(s) {
24
+ if (!/^[A-Za-z0-9_-]*$/.test(s))
25
+ throw new Error('invalid base64url');
26
+ const b64 = s.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - (s.length % 4)) % 4);
27
+ const bin = atob(b64);
28
+ const out = new Uint8Array(bin.length);
29
+ for (let i = 0; i < bin.length; i++)
30
+ out[i] = bin.charCodeAt(i);
31
+ return out;
32
+ }
33
+ const utf8 = new TextEncoder();
34
+ const utf8dec = new TextDecoder();
35
+ function subtle() {
36
+ const c = globalThis.crypto;
37
+ if (!c?.subtle)
38
+ throw new Error('WebCrypto (crypto.subtle) is not available in this runtime');
39
+ return c.subtle;
40
+ }
41
+ // ─── JWK thumbprint (RFC 7638) ───────────────────────────────────────────────────────────────────────
42
+ /** RFC 7638 thumbprint: sha256 over the JCS of the REQUIRED public members only, base64url. */
43
+ export async function jwkThumbprint(jwk) {
44
+ let required;
45
+ switch (jwk.kty) {
46
+ case 'EC':
47
+ required = { crv: must(jwk.crv, 'crv'), kty: 'EC', x: must(jwk.x, 'x'), y: must(jwk.y, 'y') };
48
+ break;
49
+ case 'OKP':
50
+ required = { crv: must(jwk.crv, 'crv'), kty: 'OKP', x: must(jwk.x, 'x') };
51
+ break;
52
+ case 'RSA':
53
+ required = { e: must(jwk.e, 'e'), kty: 'RSA', n: must(jwk.n, 'n') };
54
+ break;
55
+ default:
56
+ throw new Error(`jwkThumbprint: unsupported kty "${String(jwk.kty)}"`);
57
+ }
58
+ const digest = await subtle().digest('SHA-256', utf8.encode(jcsCanonicalize(required)));
59
+ return base64UrlEncode(new Uint8Array(digest));
60
+ }
61
+ function must(v, name) {
62
+ if (typeof v !== 'string' || v.length === 0)
63
+ throw new Error(`jwkThumbprint: missing JWK member "${name}"`);
64
+ return v;
65
+ }
66
+ // ─── Keys ────────────────────────────────────────────────────────────────────────────────────────────
67
+ /** Is EdDSA (Ed25519) usable here? Feature-detected, never assumed (workerd has no Ed25519). */
68
+ export async function supportsEdDSA() {
69
+ try {
70
+ await subtle().generateKey({ name: 'Ed25519' }, false, ['sign', 'verify']);
71
+ return true;
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ /** Generate a card-signing key pair. ES256 by default; `EdDSA` throws where the runtime lacks it. */
78
+ export async function generateA2ACardSigningKey(alg = 'ES256') {
79
+ const s = subtle();
80
+ const params = alg === 'ES256' ? { name: 'ECDSA', namedCurve: 'P-256' } : { name: 'Ed25519' };
81
+ const pair = (await s.generateKey(params, true, ['sign', 'verify']));
82
+ const publicJwk = await s.exportKey('jwk', pair.publicKey);
83
+ delete publicJwk.key_ops;
84
+ delete publicJwk.ext;
85
+ return { alg, privateKey: pair.privateKey, publicKey: pair.publicKey, publicJwk, kid: await jwkThumbprint(publicJwk) };
86
+ }
87
+ /** Import a public JWK as a verification key for `alg`. */
88
+ export async function importVerificationKey(jwk, alg) {
89
+ const params = alg === 'ES256' ? { name: 'ECDSA', namedCurve: 'P-256' } : { name: 'Ed25519' };
90
+ return subtle().importKey('jwk', jwk, params, true, ['verify']);
91
+ }
92
+ function signParams(alg) {
93
+ return alg === 'ES256' ? { name: 'ECDSA', hash: 'SHA-256' } : { name: 'Ed25519' };
94
+ }
95
+ /** Sign the canonical card bytes; returns the card with the signature appended. Pure apart from the key op. */
96
+ export async function signA2ACard(card, opts) {
97
+ const alg = opts.alg ?? 'ES256';
98
+ if (!opts.kid)
99
+ throw new Error('signA2ACard: kid is required');
100
+ const protectedHeader = base64UrlEncode(utf8.encode(jcsCanonicalize({ alg, kid: opts.kid })));
101
+ const payload = base64UrlEncode(canonicalCardBytes(card));
102
+ const signingInput = utf8.encode(`${protectedHeader}.${payload}`);
103
+ const sig = new Uint8Array(await subtle().sign(signParams(alg), opts.privateKey, signingInput));
104
+ const signature = { protected: protectedHeader, signature: base64UrlEncode(sig) };
105
+ const existing = Array.isArray(card.signatures) ? card.signatures : [];
106
+ return {
107
+ card: { ...card, signatures: [...existing, signature] },
108
+ signature,
109
+ compact: `${protectedHeader}..${signature.signature}`,
110
+ payload,
111
+ };
112
+ }
113
+ /** Re-derive the canonical bytes and verify every signature entry. Fail-closed. */
114
+ export async function verifyA2ACardSignatures(card, opts) {
115
+ const verified = [];
116
+ const failures = [];
117
+ const sigs = card.signatures;
118
+ if (!Array.isArray(sigs) || sigs.length === 0) {
119
+ return { ok: false, verified, failures: [{ kid: '', reason: 'no_signatures' }] };
120
+ }
121
+ let payload;
122
+ try {
123
+ payload = base64UrlEncode(canonicalCardBytes(card));
124
+ }
125
+ catch {
126
+ return { ok: false, verified, failures: [{ kid: '', reason: 'bad_entry' }] };
127
+ }
128
+ for (const entry of sigs) {
129
+ const e = entry;
130
+ if (!e || typeof e.protected !== 'string' || typeof e.signature !== 'string') {
131
+ failures.push({ kid: '', reason: 'bad_entry' });
132
+ continue;
133
+ }
134
+ let header;
135
+ try {
136
+ header = JSON.parse(utf8dec.decode(base64UrlDecode(e.protected)));
137
+ }
138
+ catch {
139
+ failures.push({ kid: '', reason: 'bad_protected_header' });
140
+ continue;
141
+ }
142
+ const kid = typeof header.kid === 'string' ? header.kid : '';
143
+ if (!kid) {
144
+ failures.push({ kid: '', reason: 'bad_protected_header' });
145
+ continue;
146
+ }
147
+ const alg = header.alg;
148
+ if (alg !== 'ES256' && alg !== 'EdDSA') {
149
+ failures.push({ kid, reason: 'unsupported_alg' });
150
+ continue;
151
+ }
152
+ const resolved = await opts.keys(kid);
153
+ if (!resolved) {
154
+ failures.push({ kid, reason: 'unknown_kid' });
155
+ continue;
156
+ }
157
+ let key;
158
+ try {
159
+ key = isCryptoKey(resolved) ? resolved : await importVerificationKey(resolved, alg);
160
+ }
161
+ catch {
162
+ failures.push({ kid, reason: 'key_import_failed' });
163
+ continue;
164
+ }
165
+ let valid = false;
166
+ try {
167
+ valid = await subtle().verify(signParams(alg), key, base64UrlDecode(e.signature), utf8.encode(`${e.protected}.${payload}`));
168
+ }
169
+ catch {
170
+ valid = false;
171
+ }
172
+ if (valid)
173
+ verified.push(kid);
174
+ else
175
+ failures.push({ kid, reason: 'signature_invalid' });
176
+ }
177
+ return { ok: failures.length === 0 && verified.length > 0, verified, failures };
178
+ }
179
+ function isCryptoKey(k) {
180
+ return typeof k.type === 'string' && typeof k.algorithm === 'object' && !('kty' in k);
181
+ }
182
+ /** Decode a signature entry's protected header (`alg`, `kid`) without verifying anything. */
183
+ export function decodeProtectedHeader(entry) {
184
+ return JSON.parse(utf8dec.decode(base64UrlDecode(entry.protected)));
185
+ }
186
+ //# sourceMappingURL=jws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jws.js","sourceRoot":"","sources":["../../src/a2a/jws.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAiB,MAAM,gBAAgB,CAAC;AAKnE,wGAAwG;AAExG,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3F,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACtB,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAChE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;AAC/B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,SAAS,MAAM;IACb,MAAM,CAAC,GAAI,UAAkC,CAAC,MAAM,CAAC;IACrD,IAAI,CAAC,CAAC,EAAE,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAC9F,OAAO,CAAC,CAAC,MAAM,CAAC;AAClB,CAAC;AAED,wGAAwG;AAExG,+FAA+F;AAC/F,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAe;IACjD,IAAI,QAAgC,CAAC;IACrC,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC;QAChB,KAAK,IAAI;YACP,QAAQ,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YAC9F,MAAM;QACR,KAAK,KAAK;YACR,QAAQ,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YAC1E,MAAM;QACR,KAAK,KAAK;YACR,QAAQ,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YACpE,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxF,OAAO,eAAe,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,IAAI,CAAC,CAAqB,EAAE,IAAY;IAC/C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,GAAG,CAAC,CAAC;IAC5G,OAAO,CAAC,CAAC;AACX,CAAC;AAED,wGAAwG;AAExG,gGAAgG;AAChG,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAe,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACxF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAWD,qGAAqG;AACrG,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,MAAqB,OAAO;IAC1E,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;IACnB,MAAM,MAAM,GACV,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,SAAS,EAAgB,CAAC;IAChG,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAkB,CAAC;IACtF,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3D,OAAQ,SAAmC,CAAC,OAAO,CAAC;IACpD,OAAQ,SAA+B,CAAC,GAAG,CAAC;IAC5C,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;AACzH,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAe,EAAE,GAAkB;IAC7E,MAAM,MAAM,GACV,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,SAAS,EAAgB,CAAC;IAChG,OAAO,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,UAAU,CAAC,GAAkB;IACpC,OAAO,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,SAAS,EAAgB,CAAC;AACnG,CAAC;AAqBD,+GAA+G;AAC/G,MAAM,CAAC,KAAK,UAAU,WAAW,CAAqB,IAAO,EAAE,IAAwB;IACrF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC;IAChC,IAAI,CAAC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC/D,MAAM,eAAe,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9F,MAAM,OAAO,GAAG,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,eAAe,IAAI,OAAO,EAAE,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAChG,MAAM,SAAS,GAA4B,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3G,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,UAAwC,CAAC,CAAC,CAAC,EAAE,CAAC;IACtG,OAAO;QACL,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,CAAC,GAAG,QAAQ,EAAE,SAAS,CAAC,EAAE;QACvD,SAAS;QACT,OAAO,EAAE,GAAG,eAAe,KAAK,SAAS,CAAC,SAAS,EAAE;QACrD,OAAO;KACR,CAAC;AACJ,CAAC;AA2BD,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAA+B,EAC/B,IAAoC;IAEpC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAA8C,EAAE,CAAC;IAC/D,MAAM,IAAI,GAAI,IAAiB,CAAC,UAAU,CAAC;IAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;IACnF,CAAC;IACD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,eAAe,CAAC,kBAAkB,CAAC,IAAgB,CAAC,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IAC/E,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,IAAiB,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,KAAgD,CAAC;QAC3D,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;YAChD,SAAS;QACX,CAAC;QACD,IAAI,MAAwC,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAqC,CAAC;QACxG,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC,CAAC;YAC3D,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC,CAAC;YAC3D,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACvB,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAClD,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;YAC9C,SAAS;QACX,CAAC;QACD,IAAI,GAAc,CAAC;QACnB,IAAI,CAAC;YACH,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,qBAAqB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACtF,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACpD,SAAS;QACX,CAAC;QACD,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,MAAM,EAAE,CAAC,MAAM,CAC3B,UAAU,CAAC,GAAG,CAAC,EACf,GAAG,EACH,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,EAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC,CACzC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,KAAK,GAAG,KAAK,CAAC;QAChB,CAAC;QACD,IAAI,KAAK;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;YACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAClF,CAAC;AAED,SAAS,WAAW,CAAC,CAAyB;IAC5C,OAAO,OAAQ,CAAe,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAQ,CAAe,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AACtH,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,qBAAqB,CAAC,KAA8B;IAClE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAmC,CAAC;AACxG,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { A2AAgentCardV1, A2AAgentExtensionV1 } from './types.js';
2
+ /** The A2A extension URI a released card carries when its playbook is public. */
3
+ /** The extension's URI, under the substrate's own namespace like every other AP extension (`agenticprimitives.org/a2a/<name>/v1`) —
4
+ * a package names no deployment domain (ADR-0021). */
5
+ export declare const PLAYBOOK_BINDING_EXT_URI = "https://agenticprimitives.org/a2a/playbook-binding/v1";
6
+ export interface PlaybookBindingV1 {
7
+ /** Canonical skill id of the archetype (`skill:<ns>/<name>`). */
8
+ archetypeId: string;
9
+ /** Exact version — NEVER 'latest' (spec 340 pinning; a historical record naming 'latest' drifts). */
10
+ archetypeVersion: string;
11
+ /** The compiled AgentHarnessDefinitionV1 digest — the content commitment verified against the corpus. */
12
+ definitionDigest: string;
13
+ }
14
+ /** Build the `capabilities.extensions[]` entry that binds a playbook to a card release. */
15
+ export declare function playbookBindingExtension(binding: PlaybookBindingV1): A2AAgentExtensionV1;
16
+ /** Read the playbook binding off a card, or null when it carries none / carries a malformed one. */
17
+ export declare function readPlaybookBinding(card: Pick<A2AAgentCardV1, 'capabilities'>): PlaybookBindingV1 | null;
18
+ /** Add (or replace) the playbook binding on a card's capabilities, returning a NEW card (cards are
19
+ * immutable once released; this builds the content a release will sign). */
20
+ export declare function withPlaybookBinding(card: A2AAgentCardV1, binding: PlaybookBindingV1): A2AAgentCardV1;
21
+ /** Among an agent's card releases, the one whose card binds this exact definition digest — the release a
22
+ * Home cites as "Bound to release r-N". Newest matching release wins (highest releaseNumber). Reads the
23
+ * signed card when present (that is what the world sees), else the unsigned one. */
24
+ export declare function playbookBoundRelease<R extends {
25
+ releaseNumber: number;
26
+ signedCard?: Pick<A2AAgentCardV1, 'capabilities'>;
27
+ unsignedCard: Pick<A2AAgentCardV1, 'capabilities'>;
28
+ }>(releases: readonly R[], definitionDigest: string): R | null;
29
+ //# sourceMappingURL=playbook-binding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playbook-binding.d.ts","sourceRoot":"","sources":["../../src/a2a/playbook-binding.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtE,iFAAiF;AACjF;uDACuD;AACvD,eAAO,MAAM,wBAAwB,0DAA0D,CAAC;AAEhG,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,qGAAqG;IACrG,gBAAgB,EAAE,MAAM,CAAC;IACzB,yGAAyG;IACzG,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,2FAA2F;AAC3F,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,iBAAiB,GAAG,mBAAmB,CASxF;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,GAAG,iBAAiB,GAAG,IAAI,CAWxG;AAED;6EAC6E;AAC7E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAMpG;AAED;;qFAEqF;AACrF,wBAAgB,oBAAoB,CAClC,CAAC,SAAS;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IAAC,YAAY,EAAE,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,CAAA;CAAE,EAC1I,QAAQ,EAAE,SAAS,CAAC,EAAE,EAAE,gBAAgB,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAO5D"}
@@ -0,0 +1,65 @@
1
+ // spec 354 K6 — the PLAYBOOK BINDING on a released A2A card.
2
+ //
3
+ // An agent's archetype assignment is a PRIVATE vault record (behavior is private posture; an org may not
4
+ // want its playbook public — spec 354 §2). When the steward chooses to make it public, a card release
5
+ // carries the compiled definition's digest as an A2A capability EXTENSION. The A2A 1.0 card model is
6
+ // closed at the top level, so the binding rides `capabilities.extensions[]` — the same mechanism the
7
+ // payment-gate and skill-provenance extensions use — never an off-spec top-level field.
8
+ //
9
+ // The binding is DISCLOSURE + VERIFIABILITY, never authority: it names WHICH playbook version a released
10
+ // card promises (canonical skill id + version + definition digest), so the world can verify that version
11
+ // against the corpus's Merkle root. It grants nothing; a playbook is never authority (spec 354 §1). The
12
+ // digest IS the content commitment — a verifier re-derives the definition digest and checks THAT against
13
+ // the corpus, exactly as `skill-provenance/v1` does at run time.
14
+ /** The A2A extension URI a released card carries when its playbook is public. */
15
+ /** The extension's URI, under the substrate's own namespace like every other AP extension (`agenticprimitives.org/a2a/<name>/v1`) —
16
+ * a package names no deployment domain (ADR-0021). */
17
+ export const PLAYBOOK_BINDING_EXT_URI = 'https://agenticprimitives.org/a2a/playbook-binding/v1';
18
+ /** Build the `capabilities.extensions[]` entry that binds a playbook to a card release. */
19
+ export function playbookBindingExtension(binding) {
20
+ return {
21
+ uri: PLAYBOOK_BINDING_EXT_URI,
22
+ // Not required for interop: a client that does not understand the binding still uses the card. The
23
+ // binding is evidence for those who verify, never a gate on reaching the agent.
24
+ required: false,
25
+ description: 'the compiled archetype playbook this card promises (verifiable against the skills corpus by digest)',
26
+ params: { archetypeId: binding.archetypeId, archetypeVersion: binding.archetypeVersion, definitionDigest: binding.definitionDigest },
27
+ };
28
+ }
29
+ /** Read the playbook binding off a card, or null when it carries none / carries a malformed one. */
30
+ export function readPlaybookBinding(card) {
31
+ const ext = (card.capabilities?.extensions ?? []).find((e) => e.uri === PLAYBOOK_BINDING_EXT_URI);
32
+ if (!ext?.params)
33
+ return null;
34
+ const p = ext.params;
35
+ const archetypeId = typeof p.archetypeId === 'string' ? p.archetypeId : '';
36
+ const archetypeVersion = typeof p.archetypeVersion === 'string' ? p.archetypeVersion : '';
37
+ const definitionDigest = typeof p.definitionDigest === 'string' ? p.definitionDigest : '';
38
+ // A binding is only meaningful if it names all three, and 'latest' is refused here too (a released card
39
+ // that promises "latest" promises nothing checkable).
40
+ if (!archetypeId || !archetypeVersion || archetypeVersion === 'latest' || !definitionDigest)
41
+ return null;
42
+ return { archetypeId, archetypeVersion, definitionDigest };
43
+ }
44
+ /** Add (or replace) the playbook binding on a card's capabilities, returning a NEW card (cards are
45
+ * immutable once released; this builds the content a release will sign). */
46
+ export function withPlaybookBinding(card, binding) {
47
+ const others = (card.capabilities?.extensions ?? []).filter((e) => e.uri !== PLAYBOOK_BINDING_EXT_URI);
48
+ return {
49
+ ...card,
50
+ capabilities: { ...card.capabilities, extensions: [...others, playbookBindingExtension(binding)] },
51
+ };
52
+ }
53
+ /** Among an agent's card releases, the one whose card binds this exact definition digest — the release a
54
+ * Home cites as "Bound to release r-N". Newest matching release wins (highest releaseNumber). Reads the
55
+ * signed card when present (that is what the world sees), else the unsigned one. */
56
+ export function playbookBoundRelease(releases, definitionDigest) {
57
+ let best = null;
58
+ for (const r of releases) {
59
+ const binding = readPlaybookBinding(r.signedCard ?? r.unsignedCard);
60
+ if (binding?.definitionDigest === definitionDigest && (!best || r.releaseNumber > best.releaseNumber))
61
+ best = r;
62
+ }
63
+ return best;
64
+ }
65
+ //# sourceMappingURL=playbook-binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playbook-binding.js","sourceRoot":"","sources":["../../src/a2a/playbook-binding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * RFC 6901 JSON Pointer helpers — pure, immutable (`setAtPointer` returns a structural copy).
3
+ * Shared by field bindings (provenance is keyed by pointer), validation (`sourcePointer`) and import
4
+ * (`unknownFields`).
5
+ */
6
+ export declare function parsePointer(pointer: string): string[];
7
+ export declare function escapePointerToken(token: string): string;
8
+ export declare function joinPointer(...tokens: (string | number)[]): string;
9
+ /** Value at `pointer`, or `undefined` when any step is missing. Never throws on a missing path. */
10
+ export declare function getAtPointer(root: unknown, pointer: string): unknown;
11
+ /** Copy of `root` with `value` placed at `pointer` (intermediate objects created; `undefined` deletes). */
12
+ export declare function setAtPointer<T>(root: T, pointer: string, value: unknown): T;
13
+ //# sourceMappingURL=pointer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../../src/a2a/pointer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAOtD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,WAAW,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,CAElE;AAED,mGAAmG;AACnG,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAapE;AAED,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,CAI3E"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * RFC 6901 JSON Pointer helpers — pure, immutable (`setAtPointer` returns a structural copy).
3
+ * Shared by field bindings (provenance is keyed by pointer), validation (`sourcePointer`) and import
4
+ * (`unknownFields`).
5
+ */
6
+ export function parsePointer(pointer) {
7
+ if (pointer === '')
8
+ return [];
9
+ if (!pointer.startsWith('/'))
10
+ throw new Error(`invalid JSON pointer "${pointer}" (must start with "/")`);
11
+ return pointer
12
+ .slice(1)
13
+ .split('/')
14
+ .map((t) => t.replace(/~1/g, '/').replace(/~0/g, '~'));
15
+ }
16
+ export function escapePointerToken(token) {
17
+ return token.replace(/~/g, '~0').replace(/\//g, '~1');
18
+ }
19
+ export function joinPointer(...tokens) {
20
+ return tokens.map((t) => `/${escapePointerToken(String(t))}`).join('');
21
+ }
22
+ /** Value at `pointer`, or `undefined` when any step is missing. Never throws on a missing path. */
23
+ export function getAtPointer(root, pointer) {
24
+ let cur = root;
25
+ for (const token of parsePointer(pointer)) {
26
+ if (cur === null || typeof cur !== 'object')
27
+ return undefined;
28
+ if (Array.isArray(cur)) {
29
+ const idx = Number(token);
30
+ if (!Number.isInteger(idx) || idx < 0)
31
+ return undefined;
32
+ cur = cur[idx];
33
+ }
34
+ else {
35
+ cur = cur[token];
36
+ }
37
+ }
38
+ return cur;
39
+ }
40
+ /** Copy of `root` with `value` placed at `pointer` (intermediate objects created; `undefined` deletes). */
41
+ export function setAtPointer(root, pointer, value) {
42
+ const tokens = parsePointer(pointer);
43
+ if (tokens.length === 0)
44
+ return value;
45
+ return setRec(root, tokens, 0, value);
46
+ }
47
+ function setRec(node, tokens, i, value) {
48
+ const token = tokens[i];
49
+ const last = i === tokens.length - 1;
50
+ if (Array.isArray(node)) {
51
+ const idx = token === '-' ? node.length : Number(token);
52
+ if (!Number.isInteger(idx) || idx < 0)
53
+ throw new Error(`invalid array index "${token}" in pointer`);
54
+ const copy = node.slice();
55
+ if (last) {
56
+ if (value === undefined)
57
+ copy.splice(idx, 1);
58
+ else
59
+ copy[idx] = value;
60
+ }
61
+ else {
62
+ copy[idx] = setRec(copy[idx], tokens, i + 1, value);
63
+ }
64
+ return copy;
65
+ }
66
+ const obj = node !== null && typeof node === 'object' ? { ...node } : {};
67
+ if (last) {
68
+ if (value === undefined)
69
+ delete obj[token];
70
+ else
71
+ obj[token] = value;
72
+ }
73
+ else {
74
+ obj[token] = setRec(obj[token], tokens, i + 1, value);
75
+ }
76
+ return obj;
77
+ }
78
+ //# sourceMappingURL=pointer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer.js","sourceRoot":"","sources":["../../src/a2a/pointer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Card release lifecycle (spec 347 §3):
3
+ *
4
+ * draft → validated → approvalPending → approved → signed → published → { superseded | deprecated | revoked }
5
+ *
6
+ * A release is immutable and identified by release id AND content digest. Editing at `approved` or later
7
+ * forks a NEW draft (`forkDraft`). Superseding never erases; revocation records reason, authority, date and
8
+ * successor, and a revoked release is not projection-ready. Every function here is pure and returns a new
9
+ * object; illegal moves throw `A2ACardLifecycleError` instead of being ignored.
10
+ */
11
+ import type { ApprovalRefV1 } from '@agenticprimitives/types';
12
+ import type { A2AAgentCardDraftV1, A2AAgentCardReleaseV1, A2AAgentCardSignatureV1, A2AAgentCardV1, CardReleaseState, SignedSmartAgentCardBindingV1 } from './types.js';
13
+ import { validateA2ACard, type ValidateA2ACardOptions } from './validation.js';
14
+ export declare class A2ACardLifecycleError extends Error {
15
+ readonly from: CardReleaseState | 'draft';
16
+ readonly to: CardReleaseState;
17
+ constructor(message: string, from: CardReleaseState | 'draft', to: CardReleaseState);
18
+ }
19
+ /** Legal transitions. `revoked` is reachable from every non-terminal state via `revoke()`. */
20
+ export declare const CARD_RELEASE_TRANSITIONS: Readonly<Record<CardReleaseState, readonly CardReleaseState[]>>;
21
+ export declare const TERMINAL_RELEASE_STATES: ReadonlySet<CardReleaseState>;
22
+ /** Can a projection consume this release? Only approved-and-signed (or published) releases, never revoked. */
23
+ export declare function isProjectionReady(r: A2AAgentCardReleaseV1): boolean;
24
+ export interface CreateReleaseOptions {
25
+ releaseId?: string;
26
+ releaseNumber: number;
27
+ agentVersion: string;
28
+ /** ISO timestamp (pure — caller's clock). */
29
+ now: string;
30
+ /** Validation context; the release is refused when validation has ERRORS. */
31
+ validation: ValidateA2ACardOptions;
32
+ supersedes?: string;
33
+ }
34
+ export declare class A2ACardValidationError extends Error {
35
+ readonly diagnostics: ReturnType<typeof validateA2ACard>;
36
+ constructor(diagnostics: ReturnType<typeof validateA2ACard>);
37
+ }
38
+ /** Freeze a draft into a `validated` release. Throws `A2ACardValidationError` when validation has errors. */
39
+ export declare function createRelease(draft: A2AAgentCardDraftV1, opts: CreateReleaseOptions): A2AAgentCardReleaseV1;
40
+ export interface TransitionContext {
41
+ now: string;
42
+ /** Required for `approvalPending → approved`; MUST name this release's `unsignedContentDigest`. */
43
+ approval?: ApprovalRefV1;
44
+ /** Required for `signed → published`. */
45
+ publication?: {
46
+ uri: string;
47
+ };
48
+ /** Required for `published → superseded`. */
49
+ successor?: string;
50
+ reason?: string;
51
+ }
52
+ /** Move a release along a legal transition. Throws `A2ACardLifecycleError` otherwise. */
53
+ export declare function transition(release: A2AAgentCardReleaseV1, to: CardReleaseState, ctx: TransitionContext): A2AAgentCardReleaseV1;
54
+ export interface AttachSignatureInput {
55
+ /** The signed card as returned by `signA2ACard` — MUST be this release's unsigned card plus signatures. */
56
+ signedCard: A2AAgentCardV1;
57
+ signature: A2AAgentCardSignatureV1;
58
+ signedAt?: string;
59
+ }
60
+ /** Attach a JWS signature (state `approved` or `signed` → `signed`). Refuses a signature over other bytes. */
61
+ export declare function attachSignature(release: A2AAgentCardReleaseV1, input: AttachSignatureInput): A2AAgentCardReleaseV1;
62
+ /** Attach the SA's EIP-712 binding (state `signed` or `published`). Digests MUST match this release. */
63
+ export declare function attachSmartAgentBinding(release: A2AAgentCardReleaseV1, signed: SignedSmartAgentCardBindingV1): A2AAgentCardReleaseV1;
64
+ export interface RevokeOptions {
65
+ reason: string;
66
+ authority: string;
67
+ now: string;
68
+ successor?: string;
69
+ }
70
+ /** Revoke from any non-terminal state. Records reason / authority / date / successor; never erases. */
71
+ export declare function revoke(release: A2AAgentCardReleaseV1, opts: RevokeOptions): A2AAgentCardReleaseV1;
72
+ /** Editing after `approved` = a new draft. Starts from the release's unsigned card + bindings. */
73
+ export declare function forkDraft(release: A2AAgentCardReleaseV1, opts: {
74
+ now: string;
75
+ revision?: number;
76
+ }): A2AAgentCardDraftV1;
77
+ //# sourceMappingURL=release.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../src/a2a/release.ts"],"names":[],"mappings":"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"}