sealbridge 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/README.ja.md +6 -4
  2. package/README.md +9 -4
  3. package/dist/cli/dist/accept.d.ts +2 -1
  4. package/dist/cli/dist/accept.js +18 -7
  5. package/dist/cli/dist/accept.js.map +1 -1
  6. package/dist/cli/dist/index.js +46 -13
  7. package/dist/cli/dist/index.js.map +1 -1
  8. package/dist/cli/dist/invite-links.d.ts +14 -0
  9. package/dist/cli/dist/invite-links.js +263 -0
  10. package/dist/cli/dist/invite-links.js.map +1 -0
  11. package/dist/cli/dist/invite-output.d.ts +1 -1
  12. package/dist/cli/dist/invite-output.js +3 -2
  13. package/dist/cli/dist/invite-output.js.map +1 -1
  14. package/dist/cli/dist/network.js +16 -23
  15. package/dist/cli/dist/network.js.map +1 -1
  16. package/dist/cli/dist/receipt.d.ts +12 -2
  17. package/dist/cli/dist/receipt.js +6 -5
  18. package/dist/cli/dist/receipt.js.map +1 -1
  19. package/dist/cli/dist/sdk.d.ts +6 -4
  20. package/dist/cli/dist/sdk.js +3 -2
  21. package/dist/cli/dist/sdk.js.map +1 -1
  22. package/dist/cli/dist/task-review.d.ts +1 -8
  23. package/dist/cli/dist/task-review.js +4 -17
  24. package/dist/cli/dist/task-review.js.map +1 -1
  25. package/dist/cli/dist/tasks.js +1 -1
  26. package/dist/cli/dist/tasks.js.map +1 -1
  27. package/dist/examples/two-owner-demo/dist/run-demo.js +3 -1
  28. package/dist/examples/two-owner-demo/dist/run-demo.js.map +1 -1
  29. package/dist/package.json +1 -1
  30. package/dist/packages/core/dist/content-inspection-rules.d.ts +22 -0
  31. package/dist/packages/core/dist/content-inspection-rules.js +34 -0
  32. package/dist/packages/core/dist/content-inspection-rules.js.map +1 -0
  33. package/dist/packages/core/dist/content-inspection.d.ts +43 -0
  34. package/dist/packages/core/dist/content-inspection.js +192 -0
  35. package/dist/packages/core/dist/content-inspection.js.map +1 -0
  36. package/dist/packages/core/dist/context-grant.d.ts +13 -0
  37. package/dist/packages/core/dist/context-grant.js +65 -0
  38. package/dist/packages/core/dist/context-grant.js.map +1 -0
  39. package/dist/packages/core/dist/delegation.d.ts +17 -0
  40. package/dist/packages/core/dist/delegation.js +126 -0
  41. package/dist/packages/core/dist/delegation.js.map +1 -0
  42. package/dist/packages/core/dist/edge.d.ts +2 -0
  43. package/dist/packages/core/dist/edge.js +2 -0
  44. package/dist/packages/core/dist/edge.js.map +1 -1
  45. package/dist/packages/core/dist/index.d.ts +6 -0
  46. package/dist/packages/core/dist/index.js +6 -0
  47. package/dist/packages/core/dist/index.js.map +1 -1
  48. package/dist/packages/core/dist/invite-link.d.ts +72 -0
  49. package/dist/packages/core/dist/invite-link.js +225 -0
  50. package/dist/packages/core/dist/invite-link.js.map +1 -0
  51. package/dist/packages/core/dist/invite-sas.d.ts +7 -0
  52. package/dist/packages/core/dist/invite-sas.js +15 -0
  53. package/dist/packages/core/dist/invite-sas.js.map +1 -0
  54. package/dist/packages/core/dist/relay-auth.d.ts +1 -1
  55. package/dist/packages/core/dist/relay-auth.js +1 -1
  56. package/dist/packages/core/dist/relay-auth.js.map +1 -1
  57. package/dist/packages/core/dist/schema.d.ts +1 -1
  58. package/dist/packages/core/dist/schema.js +4 -0
  59. package/dist/packages/core/dist/schema.js.map +1 -1
  60. package/dist/packages/core/dist/types.d.ts +52 -0
  61. package/dist/packages/ledger/dist/index.d.ts +70 -2
  62. package/dist/packages/ledger/dist/index.js +404 -26
  63. package/dist/packages/ledger/dist/index.js.map +1 -1
  64. package/dist/packages/relay/dist/fetch.js +4 -0
  65. package/dist/packages/relay/dist/fetch.js.map +1 -1
  66. package/dist/packages/relay/dist/invites.d.ts +42 -0
  67. package/dist/packages/relay/dist/invites.js +347 -0
  68. package/dist/packages/relay/dist/invites.js.map +1 -0
  69. package/dist/packages/relay/dist/worker.d.ts +3 -0
  70. package/dist/packages/relay/dist/worker.js +21 -0
  71. package/dist/packages/relay/dist/worker.js.map +1 -1
  72. package/dist/packages/runtime/dist/a2a.js +1 -1
  73. package/dist/packages/runtime/dist/adapter.d.ts +1 -0
  74. package/dist/packages/runtime/dist/application-config.js +69 -6
  75. package/dist/packages/runtime/dist/application-config.js.map +1 -1
  76. package/dist/packages/runtime/dist/approval-providers.d.ts +4 -0
  77. package/dist/packages/runtime/dist/approval-providers.js +3 -0
  78. package/dist/packages/runtime/dist/approval-providers.js.map +1 -1
  79. package/dist/packages/runtime/dist/connection-persistence.d.ts +1 -1
  80. package/dist/packages/runtime/dist/context-grant-audit.d.ts +8 -0
  81. package/dist/packages/runtime/dist/context-grant-audit.js +41 -0
  82. package/dist/packages/runtime/dist/context-grant-audit.js.map +1 -0
  83. package/dist/packages/runtime/dist/delegation.d.ts +37 -0
  84. package/dist/packages/runtime/dist/delegation.js +125 -0
  85. package/dist/packages/runtime/dist/delegation.js.map +1 -0
  86. package/dist/packages/runtime/dist/gateway.d.ts +1 -0
  87. package/dist/packages/runtime/dist/gateway.js.map +1 -1
  88. package/dist/packages/runtime/dist/held-request-store.d.ts +2 -0
  89. package/dist/packages/runtime/dist/held-request-store.js +3 -2
  90. package/dist/packages/runtime/dist/held-request-store.js.map +1 -1
  91. package/dist/packages/runtime/dist/held-task-content.d.ts +14 -0
  92. package/dist/packages/runtime/dist/held-task-content.js +33 -0
  93. package/dist/packages/runtime/dist/held-task-content.js.map +1 -0
  94. package/dist/packages/runtime/dist/index.d.ts +4 -0
  95. package/dist/packages/runtime/dist/index.js +4 -0
  96. package/dist/packages/runtime/dist/index.js.map +1 -1
  97. package/dist/packages/runtime/dist/mcp-server.js +22 -8
  98. package/dist/packages/runtime/dist/mcp-server.js.map +1 -1
  99. package/dist/packages/runtime/dist/mcp-tool-catalog.js +44 -5
  100. package/dist/packages/runtime/dist/mcp-tool-catalog.js.map +1 -1
  101. package/dist/packages/runtime/dist/rule-content-review-child.d.ts +1 -0
  102. package/dist/packages/runtime/dist/rule-content-review-child.js +25 -0
  103. package/dist/packages/runtime/dist/rule-content-review-child.js.map +1 -0
  104. package/dist/packages/runtime/dist/rule-content-review.d.ts +9 -0
  105. package/dist/packages/runtime/dist/rule-content-review.js +217 -0
  106. package/dist/packages/runtime/dist/rule-content-review.js.map +1 -0
  107. package/dist/packages/runtime/dist/session-audit.d.ts +6 -1
  108. package/dist/packages/runtime/dist/session-audit.js +35 -4
  109. package/dist/packages/runtime/dist/session-audit.js.map +1 -1
  110. package/dist/packages/runtime/dist/session.d.ts +21 -1
  111. package/dist/packages/runtime/dist/session.js +429 -63
  112. package/dist/packages/runtime/dist/session.js.map +1 -1
  113. package/dist/packages/runtime/dist/task-journal.d.ts +10 -1
  114. package/dist/packages/runtime/dist/task-journal.js +26 -1
  115. package/dist/packages/runtime/dist/task-journal.js.map +1 -1
  116. package/dist/packages/runtime/dist/verifier.d.ts +5 -2
  117. package/dist/packages/runtime/dist/verifier.js +14 -4
  118. package/dist/packages/runtime/dist/verifier.js.map +1 -1
  119. package/dist/spec/audit-entry.schema.json +25 -1
  120. package/dist/spec/audit-evidence.schema.json +179 -0
  121. package/dist/spec/audit-file-record.schema.json +177 -0
  122. package/dist/spec/audit-interruption.schema.json +110 -0
  123. package/dist/spec/context-grant-audit-payload.schema.json +24 -0
  124. package/dist/spec/context-grant.schema.json +146 -0
  125. package/dist/spec/delegation-attachment.schema.json +167 -0
  126. package/dist/spec/delegation-link.schema.json +141 -0
  127. package/dist/spec/examples/context-pooling/approval_redelegation/sample-delegation-attachment.json +413 -0
  128. package/dist/spec/examples/context-pooling/hand_over/sample-context-grant.json +18 -0
  129. package/dist/spec/examples/context-pooling/hand_over/sample-task-manifest.0.2.0.json +94 -0
  130. package/dist/spec/examples/context-pooling/sample-context-grant-audit-payload.json +4 -0
  131. package/dist/spec/examples/context-pooling/view_only/sample-context-grant.json +18 -0
  132. package/dist/spec/examples/context-pooling/view_only/sample-task-manifest.0.2.0.json +94 -0
  133. package/dist/spec/examples/sample-audit-evidence.json +138 -0
  134. package/dist/spec/examples/sample-audit-file-record.json +31 -0
  135. package/dist/spec/examples/sample-audit-interruption.json +29 -0
  136. package/dist/spec/task-manifest.0.2.0.schema.json +87 -1
  137. package/docs/context-grants.md +221 -0
  138. package/docs/sdk.ja.md +108 -2
  139. package/docs/sdk.md +120 -2
  140. package/package.json +3 -2
@@ -0,0 +1,225 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { createCipheriv, createDecipheriv, createHmac, hkdfSync, randomBytes } from 'node:crypto';
3
+ import { DEFAULT_CLOCK_SKEW_MS, validateRelayEndpointUrl } from './discovery.js';
4
+ import { normalizeRelayOrigin } from './relay-auth.js';
5
+ export const INVITE_LINK_CONTEXT = 'sealbridge/invite-link/v1';
6
+ /** UTF-8 info labels; each HKDF uses K as IKM and an empty salt (RFC 5869). */
7
+ export const INVITE_LINK_HKDF_INFO = Object.freeze({
8
+ id: INVITE_LINK_CONTEXT + '/id',
9
+ encKey: INVITE_LINK_CONTEXT + '/enc-key',
10
+ accessKey: INVITE_LINK_CONTEXT + '/access-key',
11
+ });
12
+ export const INVITE_LINK_PAD_BLOCK_BYTES = 4096;
13
+ export const INVITE_LINK_MAX_PADDED_BYTES = 16384;
14
+ export const INVITE_LINK_DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
15
+ export const INVITE_LINK_MAX_TTL_MS = 72 * 60 * 60 * 1000;
16
+ export const INVITE_LINK_TOKEN_GRACE_MS = 24 * 60 * 60 * 1000;
17
+ const NONCE_BYTES = 12;
18
+ const AUTH_TAG_BYTES = 16;
19
+ const MAX_LINK_CHARS = 2048;
20
+ const DEFAULT_RELAY = 'https://relay.sealbridge.dev';
21
+ function decodeBase64url(value, minBytes, maxBytes = minBytes) {
22
+ if (typeof value !== 'string' || value.length > Math.ceil(maxBytes * 4 / 3) ||
23
+ !/^[A-Za-z0-9_-]+$/.test(value))
24
+ throw new Error('INVALID_INVITE_LINK_ENCODING');
25
+ const bytes = Buffer.from(value, 'base64url');
26
+ if (bytes.length < minBytes || bytes.length > maxBytes || bytes.toString('base64url') !== value)
27
+ throw new Error('INVALID_INVITE_LINK_ENCODING');
28
+ return bytes;
29
+ }
30
+ function assertBytes(value, length) {
31
+ if (!(value instanceof Uint8Array) || value.byteLength !== length)
32
+ throw new Error('INVALID_INVITE_LINK_BYTES');
33
+ }
34
+ /** Expiries on the storage boundary must be UTC ISO strings with milliseconds. */
35
+ function canonicalExpiry(expiresAt) {
36
+ if (typeof expiresAt !== 'string' || expiresAt.length !== 24 || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(expiresAt) ||
37
+ !Number.isFinite(Date.parse(expiresAt)) || new Date(expiresAt).toISOString() !== expiresAt)
38
+ throw new Error('INVALID_INVITE_LINK_EXPIRY');
39
+ return expiresAt;
40
+ }
41
+ /** Returns the link deadline and the inner token deadline (link + 24 hours). */
42
+ export function inviteLinkExpiry(now = Date.now(), ttlMs = INVITE_LINK_DEFAULT_TTL_MS) {
43
+ if (!Number.isSafeInteger(now) || !Number.isSafeInteger(ttlMs) || ttlMs <= 0 || ttlMs > INVITE_LINK_MAX_TTL_MS)
44
+ throw new Error('INVALID_INVITE_LINK_EXPIRY');
45
+ try {
46
+ return {
47
+ expiresAt: canonicalExpiry(new Date(now + ttlMs).toISOString()),
48
+ tokenExpiresAt: canonicalExpiry(new Date(now + ttlMs + INVITE_LINK_TOKEN_GRACE_MS).toISOString()),
49
+ };
50
+ }
51
+ catch {
52
+ throw new Error('INVALID_INVITE_LINK_EXPIRY');
53
+ }
54
+ }
55
+ /** The returned k is exactly 43 unpadded base64url characters encoding 32 random bytes. */
56
+ export function generateInviteLinkKey() {
57
+ return randomBytes(32).toString('base64url');
58
+ }
59
+ export function deriveInviteLinkKeys(k) {
60
+ const key = decodeBase64url(k, 32);
61
+ const derive = (info, length) => Buffer.from(hkdfSync('sha256', key, Buffer.alloc(0), info, length));
62
+ return {
63
+ id: derive(INVITE_LINK_HKDF_INFO.id, 16),
64
+ encKey: derive(INVITE_LINK_HKDF_INFO.encKey, 32),
65
+ accessKey: derive(INVITE_LINK_HKDF_INFO.accessKey, 32),
66
+ };
67
+ }
68
+ /** Exact bytes: HMAC-SHA256(accessKey, UTF8("claim") || raw 16-byte id). */
69
+ export function inviteLinkClaimTag(accessKey, id) {
70
+ assertBytes(accessKey, 32);
71
+ assertBytes(id, 16);
72
+ return createHmac('sha256', accessKey).update('claim', 'utf8').update(id).digest();
73
+ }
74
+ /**
75
+ * AAD = UTF8(context) || raw id || UTF8(normalizeRelayOrigin(relayOrigin)) ||
76
+ * UTF8(expiresAt). No separators, length prefixes, JSON, or terminating NULs.
77
+ * The origin has no path, trailing slash, or default port; ws(s) maps to http(s).
78
+ */
79
+ export function inviteLinkAad(id, relayOrigin, expiresAt) {
80
+ assertBytes(id, 16);
81
+ return Buffer.concat([Buffer.from(INVITE_LINK_CONTEXT), id,
82
+ Buffer.from(normalizeRelayOrigin(relayOrigin)), Buffer.from(canonicalExpiry(expiresAt))]);
83
+ }
84
+ /** Four-byte big-endian UTF-8 byte length, token bytes, then zero padding. */
85
+ export function padInviteLinkToken(token) {
86
+ if (typeof token !== 'string' || !token)
87
+ throw new Error('INVALID_INVITE_LINK_PLAINTEXT');
88
+ if (token.length > INVITE_LINK_MAX_PADDED_BYTES - 4)
89
+ throw new Error('INVITE_LINK_TOO_LARGE');
90
+ const size = Buffer.byteLength(token, 'utf8');
91
+ if (size > INVITE_LINK_MAX_PADDED_BYTES - 4)
92
+ throw new Error('INVITE_LINK_TOO_LARGE');
93
+ if (Buffer.from(token, 'utf8').toString('utf8') !== token)
94
+ throw new Error('INVALID_INVITE_LINK_PLAINTEXT');
95
+ const padded = Buffer.alloc(Math.ceil((size + 4) / INVITE_LINK_PAD_BLOCK_BYTES) * INVITE_LINK_PAD_BLOCK_BYTES);
96
+ padded.writeUInt32BE(size);
97
+ padded.write(token, 4, size, 'utf8');
98
+ return padded;
99
+ }
100
+ export function unpadInviteLinkToken(padded) {
101
+ if (!(padded instanceof Uint8Array) || !validPaddedSize(padded.byteLength))
102
+ throw new Error('INVALID_INVITE_LINK_PLAINTEXT');
103
+ const bytes = Buffer.from(padded), size = bytes.readUInt32BE();
104
+ if (!size || size > bytes.length - 4 ||
105
+ Math.ceil((size + 4) / INVITE_LINK_PAD_BLOCK_BYTES) * INVITE_LINK_PAD_BLOCK_BYTES !== bytes.length ||
106
+ bytes.subarray(4 + size).some(byte => byte !== 0))
107
+ throw new Error('INVALID_INVITE_LINK_PLAINTEXT');
108
+ const tokenBytes = bytes.subarray(4, 4 + size), token = tokenBytes.toString('utf8');
109
+ if (!Buffer.from(token, 'utf8').equals(tokenBytes))
110
+ throw new Error('INVALID_INVITE_LINK_PLAINTEXT');
111
+ return token;
112
+ }
113
+ function validPaddedSize(size) {
114
+ return size >= INVITE_LINK_PAD_BLOCK_BYTES && size <= INVITE_LINK_MAX_PADDED_BYTES &&
115
+ size % INVITE_LINK_PAD_BLOCK_BYTES === 0;
116
+ }
117
+ function validateCiphertext(value) {
118
+ assertBytes(value.id, 16);
119
+ assertBytes(value.nonce, NONCE_BYTES);
120
+ if (!(value.ciphertext instanceof Uint8Array) || !validPaddedSize(value.ciphertext.byteLength - AUTH_TAG_BYTES))
121
+ throw new Error('INVALID_INVITE_LINK_CIPHERTEXT');
122
+ canonicalExpiry(value.expiresAt);
123
+ }
124
+ export function packInviteLinkCiphertext(value) {
125
+ validateCiphertext(value);
126
+ return {
127
+ id: Buffer.from(value.id).toString('base64url'),
128
+ ciphertext: Buffer.from(value.ciphertext).toString('base64url'),
129
+ nonce: Buffer.from(value.nonce).toString('base64url'),
130
+ expiresAt: value.expiresAt,
131
+ };
132
+ }
133
+ /** Strict local decoding of an untrusted relay response, without contacting a relay. */
134
+ export function unpackInviteLinkCiphertext(value) {
135
+ if (!value || typeof value !== 'object' || Array.isArray(value) ||
136
+ Object.keys(value).length !== 4 ||
137
+ !['id', 'ciphertext', 'nonce', 'expiresAt'].every(key => Object.hasOwn(value, key)))
138
+ throw new Error('INVALID_INVITE_LINK_STORAGE');
139
+ const record = value;
140
+ const decoded = {
141
+ id: decodeBase64url(record.id, 16),
142
+ ciphertext: decodeBase64url(record.ciphertext, INVITE_LINK_PAD_BLOCK_BYTES + AUTH_TAG_BYTES, INVITE_LINK_MAX_PADDED_BYTES + AUTH_TAG_BYTES),
143
+ nonce: decodeBase64url(record.nonce, NONCE_BYTES),
144
+ expiresAt: canonicalExpiry(record.expiresAt),
145
+ };
146
+ validateCiphertext(decoded);
147
+ return decoded;
148
+ }
149
+ /** Opaque token wrapping only. Signature/card/relay verification remains the caller's next step. */
150
+ export function encryptInviteLink(token, k, options) {
151
+ const now = options.now ?? Date.now(), deadline = Date.parse(canonicalExpiry(options.expiresAt));
152
+ if (!Number.isSafeInteger(now) || deadline <= now || deadline - now > INVITE_LINK_MAX_TTL_MS)
153
+ throw new Error('INVALID_INVITE_LINK_EXPIRY');
154
+ const keys = deriveInviteLinkKeys(k), nonce = randomBytes(NONCE_BYTES);
155
+ const cipher = createCipheriv('aes-256-gcm', keys.encKey, nonce, { authTagLength: AUTH_TAG_BYTES });
156
+ cipher.setAAD(inviteLinkAad(keys.id, options.relayOrigin, options.expiresAt));
157
+ const ciphertext = Buffer.concat([cipher.update(padInviteLinkToken(token)), cipher.final(), cipher.getAuthTag()]);
158
+ return { id: keys.id, nonce, ciphertext, expiresAt: options.expiresAt };
159
+ }
160
+ export function decryptInviteLink(value, k, relayOrigin, now = Date.now()) {
161
+ try {
162
+ validateCiphertext(value);
163
+ if (!Number.isSafeInteger(now) || Date.parse(value.expiresAt) <= now - DEFAULT_CLOCK_SKEW_MS)
164
+ throw new Error();
165
+ const keys = deriveInviteLinkKeys(k);
166
+ if (!keys.id.equals(value.id))
167
+ throw new Error();
168
+ const ciphertext = Buffer.from(value.ciphertext);
169
+ const decipher = createDecipheriv('aes-256-gcm', keys.encKey, value.nonce, { authTagLength: AUTH_TAG_BYTES });
170
+ decipher.setAAD(inviteLinkAad(value.id, relayOrigin, value.expiresAt));
171
+ decipher.setAuthTag(ciphertext.subarray(-AUTH_TAG_BYTES));
172
+ return unpadInviteLinkToken(Buffer.concat([decipher.update(ciphertext.subarray(0, -AUTH_TAG_BYTES)), decipher.final()]));
173
+ }
174
+ catch {
175
+ throw new Error('INVITE_LINK_DECRYPTION_FAILED');
176
+ }
177
+ }
178
+ function normalizeAllowlistUrl(value, policy) {
179
+ validateRelayEndpointUrl(value, policy);
180
+ const url = new URL(value);
181
+ return url.origin + url.pathname.replace(/\/+$/, '');
182
+ }
183
+ /** Only the two v1 fragment forms are accepted. Parsing performs no network I/O. */
184
+ export function parseInviteLink(uri, policy = {}) {
185
+ if (typeof uri !== 'string' || uri.length > MAX_LINK_CHARS || /\s/.test(uri))
186
+ throw new Error('INVALID_INVITE_LINK');
187
+ // Match the literal URL prefix: URL normalization must not erase a query,
188
+ // credentials, default port, dot-segment path, control character, or extra slash.
189
+ const match = /^(?:https:\/\/sealbridge\.app\/j|sealbridge:\/\/join)#([^\s#?]+)$/.exec(uri);
190
+ if (!match)
191
+ throw new Error('INVALID_INVITE_LINK');
192
+ const fields = new Map();
193
+ for (const field of match[1].split('&')) {
194
+ const part = /^(v|k|r)=([^=]+)$/.exec(field);
195
+ if (!part || fields.has(part[1]))
196
+ throw new Error('INVALID_INVITE_LINK');
197
+ fields.set(part[1], part[2]);
198
+ }
199
+ if (fields.get('v') !== '1' || !fields.has('k'))
200
+ throw new Error('INVALID_INVITE_LINK');
201
+ const k = fields.get('k');
202
+ decodeBase64url(k, 32);
203
+ let relayOrigin = DEFAULT_RELAY;
204
+ if (fields.has('r')) {
205
+ let host;
206
+ try {
207
+ host = decodeURIComponent(fields.get('r'));
208
+ }
209
+ catch {
210
+ throw new Error('INVALID_INVITE_LINK');
211
+ }
212
+ // r is a host[:port], including bracketed IPv6, never a URL or a path.
213
+ if (/\s/.test(host) || !/^[A-Za-z0-9.\[\]:-]+$/.test(host))
214
+ throw new Error('INVALID_INVITE_LINK');
215
+ const relay = 'https://' + host;
216
+ validateRelayEndpointUrl(relay, policy);
217
+ relayOrigin = normalizeRelayOrigin(relay);
218
+ }
219
+ validateRelayEndpointUrl(relayOrigin, policy);
220
+ if (policy.allowedRelayUrls !== undefined &&
221
+ !policy.allowedRelayUrls.map(value => normalizeAllowlistUrl(value, policy)).includes(relayOrigin))
222
+ throw new Error('INVITE_LINK_RELAY_NOT_ALLOWED');
223
+ return { v: 1, k, relayOrigin };
224
+ }
225
+ //# sourceMappingURL=invite-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invite-link.js","sourceRoot":"","sources":["../src/invite-link.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Link-path verification number. inviteDigest is the existing canonical
3
+ * `sha256:<64 lowercase hex digits>` string (digest of the verified Invite),
4
+ * encoded as UTF-8 including the prefix, not decoded hex or a hash of token text.
5
+ * Read the first four SHA-256 bytes as an unsigned big-endian integer.
6
+ */
7
+ export declare function inviteLinkVerificationNumber(inviteDigest: string): string;
@@ -0,0 +1,15 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { createHash } from 'node:crypto';
3
+ /**
4
+ * Link-path verification number. inviteDigest is the existing canonical
5
+ * `sha256:<64 lowercase hex digits>` string (digest of the verified Invite),
6
+ * encoded as UTF-8 including the prefix, not decoded hex or a hash of token text.
7
+ * Read the first four SHA-256 bytes as an unsigned big-endian integer.
8
+ */
9
+ export function inviteLinkVerificationNumber(inviteDigest) {
10
+ if (typeof inviteDigest !== 'string' || inviteDigest.length !== 71 || !/^sha256:[0-9a-f]{64}$/.test(inviteDigest))
11
+ throw new Error('INVALID_INVITE_DIGEST');
12
+ const hash = createHash('sha256').update('sealbridge/sas/v1', 'utf8').update(inviteDigest, 'utf8').digest();
13
+ return (hash.readUInt32BE(0) % 1_000_000).toString().padStart(6, '0');
14
+ }
15
+ //# sourceMappingURL=invite-sas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invite-sas.js","sourceRoot":"","sources":["../src/invite-sas.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAAC,YAAoB;IAC/D,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,MAAM,KAAK,EAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC;QAC/G,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5G,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACxE,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { KeyPair } from './types.js';
2
- export type RelayAuthAction = 'receive' | 'stream' | 'subscribe';
2
+ export type RelayAuthAction = 'receive' | 'stream' | 'subscribe' | 'invite-manage';
3
3
  export interface RelayAuthPayload {
4
4
  type: 'RelayAuth';
5
5
  recipientDid: string;
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { signPayload, verifySigned } from './crypto.js';
4
- const RELAY_AUTH_ACTIONS = new Set(['receive', 'stream', 'subscribe']);
4
+ const RELAY_AUTH_ACTIONS = new Set(['receive', 'stream', 'subscribe', 'invite-manage']);
5
5
  /**
6
6
  * Canonical origin for HTTP, SSE, and WebSocket on the same host:port.
7
7
  * `ws:` becomes `http:` and `wss:` becomes `https:` before `origin` is taken.
@@ -1 +1 @@
1
- {"version":3,"file":"relay-auth.js","sourceRoot":"","sources":["../src/relay-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relay-auth.js","sourceRoot":"","sources":["../src/relay-auth.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { Ajv2020 } from 'ajv/dist/2020.js';
2
2
  import type { TaskManifest, Schema } from './types.js';
3
3
  export declare function createAjv(): Ajv2020;
4
4
  export declare const specDirectory: URL;
5
- export declare const SCHEMA_NAMES: readonly ["task-manifest", "task-manifest.0.1.0", "task-manifest.0.2.0", "agent-card", "delivery-status", "envelope", "usage-receipt", "ack-receipt", "capability-token", "approval-receipt", "audit-entry"];
5
+ export declare const SCHEMA_NAMES: readonly ["task-manifest", "task-manifest.0.1.0", "task-manifest.0.2.0", "agent-card", "delivery-status", "envelope", "usage-receipt", "ack-receipt", "capability-token", "approval-receipt", "audit-entry", "context-grant", "context-grant-audit-payload", "delegation-link", "delegation-attachment", "audit-interruption", "audit-evidence", "audit-file-record"];
6
6
  export declare function loadSchema(name: string): Schema;
7
7
  /** Spec files are static. Rebuilding Ajv for every envelope check dominates a session. */
8
8
  export declare function schemaRegistry(): Ajv2020;
@@ -3,6 +3,7 @@ import { readFileSync, readdirSync } from 'node:fs';
3
3
  import { Ajv2020 } from 'ajv/dist/2020.js';
4
4
  import formats from 'ajv-formats';
5
5
  import { isManifestProtocolVersion } from './protocol.js';
6
+ import { validateManifestContextGrant } from './context-grant.js';
6
7
  export function createAjv() {
7
8
  const ajv = new Ajv2020({ allErrors: true, strict: false, validateFormats: true });
8
9
  formats(ajv);
@@ -12,6 +13,8 @@ export const specDirectory = new URL('../../../spec/', import.meta.url);
12
13
  export const SCHEMA_NAMES = [
13
14
  'task-manifest', 'task-manifest.0.1.0', 'task-manifest.0.2.0', 'agent-card',
14
15
  'delivery-status', 'envelope', 'usage-receipt', 'ack-receipt', 'capability-token', 'approval-receipt', 'audit-entry',
16
+ 'context-grant', 'context-grant-audit-payload', 'delegation-link', 'delegation-attachment',
17
+ 'audit-interruption', 'audit-evidence', 'audit-file-record',
15
18
  ];
16
19
  export function loadSchema(name) {
17
20
  if (!SCHEMA_NAMES.some(known => known === name))
@@ -43,6 +46,7 @@ export function validateManifest(value) {
43
46
  if (version !== undefined && !isManifestProtocolVersion(version))
44
47
  throw new Error('PROTOCOL_VERSION_UNSUPPORTED');
45
48
  validateSchema(isManifestProtocolVersion(version) ? 'task-manifest.' + version : 'task-manifest', value);
49
+ validateManifestContextGrant(value);
46
50
  }
47
51
  export function assertSynchronousSchema(schema) {
48
52
  if (!schema || typeof schema !== 'object')
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,OAAO,MAAM,aAAa,CAAC;AAElC,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,OAA2C,CAAC,GAAG,CAAC,CAAC;IAClD,OAAO,GAAG,CAAC;AACb,CAAC;AACD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxE,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,eAAe,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,YAAY;IAC3E,iBAAiB,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,aAAa;IACpH,eAAe,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,uBAAuB;IAC1F,oBAAoB,EAAE,gBAAgB,EAAE,mBAAmB;CACnD,CAAC;AACX,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACxF,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,cAAc,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAW,CAAC;AACnG,CAAC;AACD,IAAI,cAAwD,CAAC;AAC7D,0FAA0F;AAC1F,MAAM,UAAU,cAAc;IAC5B,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAC1C,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QAClF,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9D,cAAc,GAAG,GAAG,CAAC;IACrB,OAAO,GAAG,CAAC;AACb,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAc;IACzD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACxF,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,CAAE,CAAC;IACtC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAChG,CAAC;AACD,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,MAAM,OAAO,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzE,CAAC,CAAE,KAAuC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;IACzE,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,cAAc,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,gBAAgB,GAAG,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACzG,4BAA4B,CAAC,KAAqB,CAAC,CAAC;AACtD,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAC,MAAe;IACrD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO;IAClD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC/E,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,uBAAuB,CAAC,KAAK,CAAC,CAAC;AAC5E,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,KAAc;IAC3D,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AACrD,CAAC"}
@@ -97,6 +97,7 @@ export interface BudgetSpec {
97
97
  onOverrun: 'hard_stop' | 'request_hitl_amendment';
98
98
  }
99
99
  export interface TaskManifest {
100
+ contextGrant?: ContextGrant;
100
101
  protocolVersion: string;
101
102
  taskId: string;
102
103
  createdAt: string;
@@ -170,3 +171,54 @@ export interface TaskManifest {
170
171
  };
171
172
  signatures?: Record<string, Signature>;
172
173
  }
174
+ export type DeliveryMode = 'view_only' | 'approval_redelegation' | 'hand_over';
175
+ export interface ContextGrant {
176
+ deliveryMode: DeliveryMode;
177
+ /** Opaque selection declarations; CP1 does not extract data from a source. */
178
+ selectors: string[];
179
+ fieldsAllowed?: string[];
180
+ fieldsDenied?: string[];
181
+ angle: string;
182
+ expiresAt: string;
183
+ maxBytes: number;
184
+ retention: 'ephemeral_view' | 'keep_deliverable';
185
+ inputRetentionAllowed?: boolean;
186
+ outputSchema?: Schema;
187
+ }
188
+ export type ContextGrantOptions = Pick<ContextGrant, 'selectors' | 'angle'> & Partial<Omit<ContextGrant, 'selectors' | 'angle'>>;
189
+ export type ContextGrantAuditEventType = 'CONTEXT_GRANT' | 'CONTEXT_OPENED' | 'CONTEXT_DISCARDED' | 'CONTEXT_DELETION_ATTEMPTED' | 'CONTEXT_MODE';
190
+ export interface ContextGrantAuditPayload {
191
+ grantDigest: string;
192
+ deliveryMode: DeliveryMode;
193
+ }
194
+ /** Cross-task provenance, distinct from the same-task capability chain. */
195
+ export interface DelegationLimits {
196
+ deadline: string;
197
+ expiresAt: string;
198
+ budget: TaskManifest['budget'];
199
+ sandboxPolicy: TaskManifest['sandboxPolicy'];
200
+ verification: TaskManifest['verification'];
201
+ depthRemaining: number;
202
+ }
203
+ export interface DelegationLinkPayload {
204
+ type: 'DelegationLink';
205
+ parentTaskId: string;
206
+ parentContractDigest: string;
207
+ childTaskId: string;
208
+ childContractDigest: string;
209
+ delegatorOwnerDid: string;
210
+ delegateeOwnerDid: string;
211
+ depthRemaining: number;
212
+ limits: DelegationLimits;
213
+ issuedAt: string;
214
+ prevLinkDigest: string | null;
215
+ }
216
+ export type DelegationLink = Signed<DelegationLinkPayload>;
217
+ export interface DelegationProof {
218
+ link: DelegationLink;
219
+ childContract: import('./contract.js').TaskContract;
220
+ }
221
+ export interface DelegationAttachment {
222
+ parentContract: import('./contract.js').TaskContract;
223
+ children: DelegationProof[];
224
+ }
@@ -28,23 +28,64 @@ export interface AuditBundle {
28
28
  receiver: Signed<Signed<Checkpoint>>;
29
29
  };
30
30
  }
31
+ /** Local storage format 1; never a wire event or bilateral checkpoint. */
32
+ export interface AuditInterruption {
33
+ type: 'AuditInterruption';
34
+ formatVersion: 1;
35
+ taskId: string;
36
+ actors: [string, string];
37
+ seq: number;
38
+ prevEntryHash: string;
39
+ acknowledgedPrefix: {
40
+ count: number;
41
+ lastSeq: number;
42
+ head: string;
43
+ entriesDigest: string;
44
+ };
45
+ phase: 'OWNER_APPROVAL' | 'ACCEPT_ACK_WAIT';
46
+ reason: 'SESSION_TIMEOUT' | 'WORKER_STOPPED' | 'WORKER_RESTART_OBSERVED';
47
+ observedAt: string;
48
+ }
49
+ export interface InterruptedAuditBundle {
50
+ entries: AuditEntry[];
51
+ interruption: Signed<AuditInterruption>;
52
+ }
53
+ export type AuditEvidence = AuditBundle | InterruptedAuditBundle;
54
+ export type AuditFileRecord = {
55
+ entry: AuditEntry;
56
+ } | {
57
+ checkpoint: AuditBundle['checkpoint'];
58
+ } | {
59
+ interruption: Signed<AuditInterruption>;
60
+ };
61
+ export interface InterruptionStore {
62
+ /** Idempotent only for exactly the same signed terminal record and prefix.
63
+ * beforeWrite must synchronously persist the signed intent; promises are rejected. */
64
+ closeInterrupted(bundle: InterruptedAuditBundle, beforeWrite?: () => void): void;
65
+ }
31
66
  export interface AuditStore {
32
67
  read(): AuditEntry[];
33
68
  append(entry: AuditEntry, checkpoint: AuditBundle['checkpoint']): void;
34
69
  seal?(checkpoint: AuditBundle['checkpoint']): void;
35
70
  }
36
- export declare class MemoryStore implements AuditStore {
71
+ export declare class MemoryStore implements AuditStore, InterruptionStore {
37
72
  #private;
38
73
  read(): AuditEntry[];
39
74
  append(entry: AuditEntry): void;
75
+ seal(checkpoint: AuditBundle['checkpoint']): void;
76
+ closeInterrupted(bundle: InterruptedAuditBundle, beforeWrite?: () => void): void;
40
77
  }
41
- export declare class JsonlStore implements AuditStore {
78
+ export declare class JsonlStore implements AuditStore, InterruptionStore {
42
79
  readonly path: string;
43
80
  constructor(path: string);
81
+ /** All cooperating writers use this exclusive file lock. Never share with an older writer.
82
+ * A lock left by process death is an explicit local recovery operation, never stolen. */
83
+ private exclusive;
44
84
  private records;
45
85
  read(): AuditEntry[];
46
86
  append(entry: AuditEntry): void;
47
87
  seal(checkpoint: AuditBundle['checkpoint']): void;
88
+ closeInterrupted(bundle: InterruptedAuditBundle, beforeWrite?: () => void): void;
48
89
  }
49
90
  export declare function parseJsonl(text: string): AuditBundle;
50
91
  export declare class BilateralLedger {
@@ -82,3 +123,30 @@ export interface AuditVerificationResult {
82
123
  */
83
124
  export declare const AUDIT_VALID_WITHOUT_TRUST_ANCHOR = "VALID (no trust anchor: truncation not checked)";
84
125
  export declare function verifyAudit(bundle: AuditBundle, expected?: AuditVerificationOptions): AuditVerificationResult;
126
+ export interface AuditEvidenceTrustAnchor extends AuditTrustAnchor {
127
+ expectedClosureKind?: 'bilateral' | 'interruption';
128
+ expectedInterruptionHash?: string;
129
+ }
130
+ export interface AuditEvidenceVerificationOptions extends AuditEvidenceTrustAnchor {
131
+ trustAnchor?: AuditEvidenceTrustAnchor;
132
+ }
133
+ export interface InterruptedAuditVerificationResult {
134
+ valid: false;
135
+ status: 'UNILATERALLY_CLOSED' | 'INVALID';
136
+ statusLabel: string;
137
+ reason: string;
138
+ prefixVerified: boolean;
139
+ terminalSignatureVerified: boolean;
140
+ bilateralCheckpointVerified: false;
141
+ trustAnchorVerified: boolean;
142
+ /** For interruption only: an actual tail condition was compared, not identity alone. */
143
+ truncationChecked: boolean;
144
+ closureKind: 'interruption';
145
+ }
146
+ export type AuditEvidenceVerificationResult = AuditVerificationResult | InterruptedAuditVerificationResult;
147
+ /** Read either terminal form, retaining physical JSONL locations out of band. */
148
+ export declare function parseAuditJsonl(text: string): AuditEvidence;
149
+ /** Both formats are verified locally. A worker-only observation never becomes VALID. */
150
+ export declare function verifyAuditEvidence(bundle: unknown, expected?: AuditEvidenceVerificationOptions): AuditEvidenceVerificationResult;
151
+ /** Creates a worker observation; callers must preserve the original prefix and journal the intent before writing. */
152
+ export declare function createAuditInterruption(entries: AuditEntry[], worker: KeyPair, phase: AuditInterruption['phase'], reason: AuditInterruption['reason'], observedAt?: string): Signed<AuditInterruption>;