@canonmsg/agent-sdk 12.5.1 → 13.0.2

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 (46) hide show
  1. package/README.md +57 -24
  2. package/dist/chunks/{chunk-C2WJT3VX.js → chunk-5WPAB5MB.js} +1047 -856
  3. package/dist/chunks/{chunk-3KFVBOVI.js → chunk-DNHJGAEL.js} +1115 -1020
  4. package/dist/chunks/chunk-DTAWEQCM.js +406 -0
  5. package/dist/chunks/{chunk-TFSURFF6.js → chunk-TYZT346O.js} +1720 -4006
  6. package/dist/chunks/chunk-YHDDOADK.js +118 -0
  7. package/dist/chunks/chunk-YJUPKU47.js +1490 -0
  8. package/dist/chunks/{mls-crypto-Y44BOSEM.js → mls-crypto-NZVMSUFU.js} +2 -1
  9. package/dist/cli.js +86 -48
  10. package/dist/drivers/acp.d.ts +56 -0
  11. package/dist/drivers/codex.d.ts +1 -2
  12. package/dist/drivers/subprocess.d.ts +38 -0
  13. package/dist/index.d.ts +4 -2
  14. package/dist/index.js +12 -3
  15. package/dist/internal/backend-contracts/endpointContentPolicy.d.ts +2 -2
  16. package/dist/internal/backend-contracts/index.d.ts +1 -0
  17. package/dist/internal/backend-contracts/loggedOutSessions.d.ts +7 -0
  18. package/dist/internal/backend-contracts/mlsDevCredential.d.ts +3 -0
  19. package/dist/internal/backend-contracts/mlsDevGroup.d.ts +17 -0
  20. package/dist/internal/core/completed-output-journal.d.ts +0 -5
  21. package/dist/internal/core/index.d.ts +3 -9
  22. package/dist/internal/core/retry.d.ts +2 -89
  23. package/dist/internal/core/silent-turn.d.ts +4 -33
  24. package/dist/internal/endpoint/engine.d.ts +6 -0
  25. package/dist/internal/endpoint/mls-dev-client.d.ts +2 -0
  26. package/dist/internal/endpoint/mls-dev-groups.d.ts +12 -0
  27. package/dist/internal/endpoint/mls-dev-text.d.ts +32 -0
  28. package/dist/internal/endpoint/node-mls-custody-protocol.d.ts +5 -0
  29. package/dist/internal/endpoint/node.d.ts +1 -0
  30. package/dist/internal/endpoint/transport.d.ts +1 -1
  31. package/dist/media.js +4 -2
  32. package/dist/mls/darwin-arm64/canon-mls-custody +0 -0
  33. package/dist/mls/linux-arm64/canon-mls-custody +0 -0
  34. package/dist/mls/linux-x64/canon-mls-custody +0 -0
  35. package/dist/mls/wasm/canon_mls_wasm.js +363 -0
  36. package/dist/mls/wasm/canon_mls_wasm_bg.wasm +0 -0
  37. package/dist/mls-wasm-host.js +258 -0
  38. package/dist/runner/mls-bundled.d.ts +15 -2
  39. package/dist/runner/mls-managed.d.ts +6 -3
  40. package/dist/runner/mls.d.ts +4 -7
  41. package/dist/runner/runner.d.ts +9 -12
  42. package/dist/runner/types.d.ts +37 -1
  43. package/package.json +1 -1
  44. package/dist/internal/core/approval-manager.d.ts +0 -43
  45. package/dist/internal/core/runtime-request-manager.d.ts +0 -283
  46. package/dist/internal/core/turn-verbosity.d.ts +0 -79
@@ -1,32 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
 
4
- // ../endpoint/src/mls-crypto.ts
5
- import { ed25519 } from "@noble/curves/ed25519.js";
6
-
7
- // ../backend-contracts/src/environment.ts
8
- var CANON_ENVIRONMENT_CONTRACTS = Object.freeze({
9
- "canon-dev-v1": Object.freeze({
10
- name: "dev",
11
- projectId: "canonmail-dev",
12
- region: "europe-west1"
13
- }),
14
- "canon-prod-v1": Object.freeze({
15
- name: "prod",
16
- projectId: "canonmail-prod",
17
- region: "europe-west1"
18
- })
19
- });
20
- function getCanonEnvironmentContract(value) {
21
- const environmentId = value.trim();
22
- const contract = CANON_ENVIRONMENT_CONTRACTS[environmentId];
23
- if (!contract) {
24
- throw new Error(`Unsupported Canon environment ID: ${value}`);
25
- }
26
- return Object.freeze({ environmentId, ...contract });
27
- }
28
- __name(getCanonEnvironmentContract, "getCanonEnvironmentContract");
29
-
30
4
  // ../backend-contracts/src/clientFloor.ts
31
5
  var CANON_CLIENT_HEADER = "X-Canon-Client";
32
6
  var CLIENT_UPDATE_REQUIRED = "CLIENT_UPDATE_REQUIRED";
@@ -76,6 +50,29 @@ var MEDIA_ORIGINS = {
76
50
  "canonmail-prod.firebasestorage.app": "https://api.canonmail.com"
77
51
  };
78
52
 
53
+ // ../backend-contracts/src/environment.ts
54
+ var CANON_ENVIRONMENT_CONTRACTS = Object.freeze({
55
+ "canon-dev-v1": Object.freeze({
56
+ name: "dev",
57
+ projectId: "canonmail-dev",
58
+ region: "europe-west1"
59
+ }),
60
+ "canon-prod-v1": Object.freeze({
61
+ name: "prod",
62
+ projectId: "canonmail-prod",
63
+ region: "europe-west1"
64
+ })
65
+ });
66
+ function getCanonEnvironmentContract(value) {
67
+ const environmentId = value.trim();
68
+ const contract = CANON_ENVIRONMENT_CONTRACTS[environmentId];
69
+ if (!contract) {
70
+ throw new Error(`Unsupported Canon environment ID: ${value}`);
71
+ }
72
+ return Object.freeze({ environmentId, ...contract });
73
+ }
74
+ __name(getCanonEnvironmentContract, "getCanonEnvironmentContract");
75
+
79
76
  // ../backend-contracts/src/media-url.ts
80
77
  function validMediaPath(path) {
81
78
  const parts = path.split("/");
@@ -123,131 +120,50 @@ function isCanonUploadUrl(url, input) {
123
120
  }
124
121
  __name(isCanonUploadUrl, "isCanonUploadUrl");
125
122
 
126
- // ../backend-contracts/src/upload-mime-types.ts
127
- var MIME_TYPE_RE = /^[a-z0-9.+-]+\/[a-z0-9.+-]+$/i;
128
- var SAFE_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set([
129
- "image/jpeg",
130
- "image/png",
131
- "image/webp",
132
- "image/gif"
133
- ]);
134
- var SAFE_AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
135
- "audio/mp4",
136
- "audio/x-m4a",
137
- "audio/mpeg",
138
- "audio/webm",
139
- "audio/ogg",
140
- "audio/wav",
141
- // ADTS AAC — the future Android streamable-memo lane; harmless standalone.
142
- "audio/aac"
143
- ]);
144
- var SAFE_VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
145
- "video/mp4",
146
- "video/quicktime",
147
- "video/webm",
148
- "video/x-m4v"
149
- ]);
150
- var SAFE_FILE_MIME_TYPES = /* @__PURE__ */ new Set([
151
- "application/pdf",
152
- "text/plain",
153
- "text/markdown",
154
- "text/x-markdown",
155
- "text/csv",
156
- "application/csv",
157
- "application/json",
158
- "application/zip",
159
- "application/vnd.ms-excel",
160
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
161
- ]);
162
- var SAFE_FILE_MIME_BY_EXTENSION = {
163
- csv: "text/csv",
164
- json: "application/json",
165
- md: "text/markdown",
166
- markdown: "text/markdown",
167
- pdf: "application/pdf",
168
- txt: "text/plain",
169
- xls: "application/vnd.ms-excel",
170
- xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
171
- zip: "application/zip"
172
- };
173
- var SAFE_VIDEO_MIME_BY_EXTENSION = {
174
- m4v: "video/x-m4v",
175
- mov: "video/quicktime",
176
- mp4: "video/mp4",
177
- webm: "video/webm"
178
- };
179
- var SAFE_AUDIO_MIME_BY_EXTENSION = {
180
- aac: "audio/aac",
181
- m4a: "audio/x-m4a",
182
- mp3: "audio/mpeg",
183
- oga: "audio/ogg",
184
- ogg: "audio/ogg",
185
- wav: "audio/wav"
186
- };
187
- function normalizeMimeType(value) {
188
- if (typeof value !== "string") return null;
189
- const normalized = value.split(";")[0].trim().toLowerCase();
190
- if (!MIME_TYPE_RE.test(normalized)) return null;
191
- if (normalized === "image/jpg") return "image/jpeg";
192
- return normalized;
193
- }
194
- __name(normalizeMimeType, "normalizeMimeType");
195
- function inferSafeFileMimeTypeFromName(value) {
196
- if (typeof value !== "string") return null;
197
- const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
198
- return SAFE_FILE_MIME_BY_EXTENSION[extension] ?? null;
123
+ // ../backend-contracts/src/mlsEnvironment.ts
124
+ var MLS_ENVIRONMENT_PROFILES = Object.freeze({
125
+ "canon-dev-v1": Object.freeze({
126
+ issuer: "canon-mls-dev-v1",
127
+ credentialType: "canon-mls-dev-credential+jws",
128
+ issuerKeyPath: "projects/canonmail-dev/locations/europe-west1/keyRings/canon-mls/cryptoKeys/device-issuer",
129
+ receiptKeyPath: "projects/canonmail-dev/locations/europe-west1/keyRings/canon-mls/cryptoKeys/feed-receipt"
130
+ }),
131
+ "canon-prod-v1": Object.freeze({
132
+ issuer: "canon-mls-prod-v1",
133
+ credentialType: "canon-mls-prod-credential+jws",
134
+ issuerKeyPath: "projects/canonmail-prod/locations/europe-west1/keyRings/canon-mls/cryptoKeys/device-issuer",
135
+ receiptKeyPath: "projects/canonmail-prod/locations/europe-west1/keyRings/canon-mls/cryptoKeys/feed-receipt"
136
+ })
137
+ });
138
+ function requireMlsEnvironmentId(value) {
139
+ if (!isMlsEnvironmentId(value)) throw new Error("INVALID_MLS_DATA");
140
+ return value;
199
141
  }
200
- __name(inferSafeFileMimeTypeFromName, "inferSafeFileMimeTypeFromName");
201
- function inferSafeVideoMimeTypeFromName(value) {
202
- if (typeof value !== "string") return null;
203
- const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
204
- return SAFE_VIDEO_MIME_BY_EXTENSION[extension] ?? null;
142
+ __name(requireMlsEnvironmentId, "requireMlsEnvironmentId");
143
+ function isMlsEnvironmentId(value) {
144
+ return typeof value === "string" && Object.hasOwn(MLS_ENVIRONMENT_PROFILES, value);
205
145
  }
206
- __name(inferSafeVideoMimeTypeFromName, "inferSafeVideoMimeTypeFromName");
207
- function inferSafeAudioMimeTypeFromName(value) {
208
- if (typeof value !== "string") return null;
209
- const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
210
- return SAFE_AUDIO_MIME_BY_EXTENSION[extension] ?? null;
146
+ __name(isMlsEnvironmentId, "isMlsEnvironmentId");
147
+ function mlsEnvironmentProfile(environmentId) {
148
+ return MLS_ENVIRONMENT_PROFILES[environmentId];
211
149
  }
212
- __name(inferSafeAudioMimeTypeFromName, "inferSafeAudioMimeTypeFromName");
213
- function shouldTrustSafeFileName(mimeType) {
214
- return !mimeType || mimeType === "application/octet-stream" || mimeType === "application/vnd.ms-excel" || mimeType === "text/plain";
150
+ __name(mlsEnvironmentProfile, "mlsEnvironmentProfile");
151
+ function mlsEnvironmentOfIssuerKeyVersion(value) {
152
+ return environmentOfKeyVersion(value, "issuerKeyPath");
215
153
  }
216
- __name(shouldTrustSafeFileName, "shouldTrustSafeFileName");
217
- function classifyAllowedUploadMimeType(value) {
218
- const mimeType = normalizeMimeType(value);
219
- if (!mimeType) return null;
220
- if (SAFE_IMAGE_MIME_TYPES.has(mimeType)) return "image";
221
- if (SAFE_AUDIO_MIME_TYPES.has(mimeType)) return "audio";
222
- if (SAFE_VIDEO_MIME_TYPES.has(mimeType)) return "video";
223
- if (SAFE_FILE_MIME_TYPES.has(mimeType)) return "file";
224
- return null;
154
+ __name(mlsEnvironmentOfIssuerKeyVersion, "mlsEnvironmentOfIssuerKeyVersion");
155
+ function mlsEnvironmentOfReceiptKeyVersion(value) {
156
+ return environmentOfKeyVersion(value, "receiptKeyPath");
225
157
  }
226
- __name(classifyAllowedUploadMimeType, "classifyAllowedUploadMimeType");
227
- function resolveAllowedUploadMimeType(input) {
228
- const normalizedMimeType = normalizeMimeType(input.mimeType);
229
- const hasExplicitMimeType = typeof input.mimeType === "string" && input.mimeType.trim().length > 0;
230
- const inferredVideoMimeType = inferSafeVideoMimeTypeFromName(input.fileName);
231
- const inferredAudioMimeType = inferSafeAudioMimeTypeFromName(input.fileName);
232
- const inferredFileMimeType = inferSafeFileMimeTypeFromName(input.fileName);
233
- if (hasExplicitMimeType && !normalizedMimeType) {
234
- return null;
235
- }
236
- if (inferredVideoMimeType && (!normalizedMimeType || normalizedMimeType === "application/octet-stream")) {
237
- return inferredVideoMimeType;
238
- }
239
- if (inferredAudioMimeType && (!normalizedMimeType || normalizedMimeType === "application/octet-stream")) {
240
- return inferredAudioMimeType;
241
- }
242
- if (inferredFileMimeType && shouldTrustSafeFileName(normalizedMimeType)) {
243
- return inferredFileMimeType;
244
- }
245
- if (normalizedMimeType && classifyAllowedUploadMimeType(normalizedMimeType)) {
246
- return normalizedMimeType;
158
+ __name(mlsEnvironmentOfReceiptKeyVersion, "mlsEnvironmentOfReceiptKeyVersion");
159
+ function environmentOfKeyVersion(value, key) {
160
+ for (const [environmentId, profile] of Object.entries(MLS_ENVIRONMENT_PROFILES)) {
161
+ const prefix = profile[key] + "/cryptoKeyVersions/";
162
+ if (value.startsWith(prefix) && /^[1-9][0-9]{0,9}$/.test(value.slice(prefix.length))) return environmentId;
247
163
  }
248
- return normalizedMimeType ? null : inferredFileMimeType;
164
+ return void 0;
249
165
  }
250
- __name(resolveAllowedUploadMimeType, "resolveAllowedUploadMimeType");
166
+ __name(environmentOfKeyVersion, "environmentOfKeyVersion");
251
167
 
252
168
  // ../backend-contracts/src/mlsDevValidation.ts
253
169
  function invalid() {
@@ -288,51 +204,6 @@ function requireMlsUuid(value) {
288
204
  }
289
205
  __name(requireMlsUuid, "requireMlsUuid");
290
206
 
291
- // ../backend-contracts/src/mlsEnvironment.ts
292
- var MLS_ENVIRONMENT_PROFILES = Object.freeze({
293
- "canon-dev-v1": Object.freeze({
294
- issuer: "canon-mls-dev-v1",
295
- credentialType: "canon-mls-dev-credential+jws",
296
- issuerKeyPath: "projects/canonmail-dev/locations/europe-west1/keyRings/canon-mls/cryptoKeys/device-issuer",
297
- receiptKeyPath: "projects/canonmail-dev/locations/europe-west1/keyRings/canon-mls/cryptoKeys/feed-receipt"
298
- }),
299
- "canon-prod-v1": Object.freeze({
300
- issuer: "canon-mls-prod-v1",
301
- credentialType: "canon-mls-prod-credential+jws",
302
- issuerKeyPath: "projects/canonmail-prod/locations/europe-west1/keyRings/canon-mls/cryptoKeys/device-issuer",
303
- receiptKeyPath: "projects/canonmail-prod/locations/europe-west1/keyRings/canon-mls/cryptoKeys/feed-receipt"
304
- })
305
- });
306
- function requireMlsEnvironmentId(value) {
307
- if (!isMlsEnvironmentId(value)) throw new Error("INVALID_MLS_DATA");
308
- return value;
309
- }
310
- __name(requireMlsEnvironmentId, "requireMlsEnvironmentId");
311
- function isMlsEnvironmentId(value) {
312
- return typeof value === "string" && Object.hasOwn(MLS_ENVIRONMENT_PROFILES, value);
313
- }
314
- __name(isMlsEnvironmentId, "isMlsEnvironmentId");
315
- function mlsEnvironmentProfile(environmentId) {
316
- return MLS_ENVIRONMENT_PROFILES[environmentId];
317
- }
318
- __name(mlsEnvironmentProfile, "mlsEnvironmentProfile");
319
- function mlsEnvironmentOfIssuerKeyVersion(value) {
320
- return environmentOfKeyVersion(value, "issuerKeyPath");
321
- }
322
- __name(mlsEnvironmentOfIssuerKeyVersion, "mlsEnvironmentOfIssuerKeyVersion");
323
- function mlsEnvironmentOfReceiptKeyVersion(value) {
324
- return environmentOfKeyVersion(value, "receiptKeyPath");
325
- }
326
- __name(mlsEnvironmentOfReceiptKeyVersion, "mlsEnvironmentOfReceiptKeyVersion");
327
- function environmentOfKeyVersion(value, key) {
328
- for (const [environmentId, profile] of Object.entries(MLS_ENVIRONMENT_PROFILES)) {
329
- const prefix = profile[key] + "/cryptoKeyVersions/";
330
- if (value.startsWith(prefix) && /^[1-9][0-9]{0,9}$/.test(value.slice(prefix.length))) return environmentId;
331
- }
332
- return void 0;
333
- }
334
- __name(environmentOfKeyVersion, "environmentOfKeyVersion");
335
-
336
207
  // ../backend-contracts/src/mlsDevEnrollment.ts
337
208
  var MLS_DEV_ENROLLMENT_CHALLENGE_TTL_MS = 3e5;
338
209
  var MLS_DEV_ENROLLMENT_MAX_BYTES = 4096;
@@ -540,6 +411,7 @@ __name(decodeCanonicalMlsBase64Url, "decodeCanonicalMlsBase64Url");
540
411
 
541
412
  // ../backend-contracts/src/mlsDevCredential.ts
542
413
  var MLS_DEV_CREDENTIAL_TTL_MS = 864e5;
414
+ var MLS_DEV_CREDENTIAL_LONG_TTL_MS = 14 * MLS_DEV_CREDENTIAL_TTL_MS;
543
415
  var MLS_DEV_CREDENTIAL_CHALLENGE_TTL_MS = 3e5;
544
416
  var MLS_DEV_CREDENTIAL_MAX_BYTES = 8192;
545
417
  var MlsDevCredentialValidationError = class extends Error {
@@ -591,8 +463,9 @@ function parseMlsDevCredentialClaims(value) {
591
463
  const input = readMlsDataRecord(value, ["version", "credentialId", "issuer", "device", "generation", "issuedAtMs", "expiresAtMs"]);
592
464
  const issuedAtMs = requireMlsInteger(input.issuedAtMs);
593
465
  const expiresAtMs = requireMlsInteger(input.expiresAtMs);
594
- if (expiresAtMs - issuedAtMs !== MLS_DEV_CREDENTIAL_TTL_MS) invalid3();
595
466
  const device = parseMlsDevEnrollmentResult({ version: 1, authorization: "registration_only", device: input.device }).device;
467
+ const lifetimeMs = expiresAtMs - issuedAtMs;
468
+ if (lifetimeMs !== MLS_DEV_CREDENTIAL_TTL_MS && (lifetimeMs !== MLS_DEV_CREDENTIAL_LONG_TTL_MS || device.principal.type !== "human")) invalid3();
596
469
  return bounded2({
597
470
  version: requireMlsLiteral(input.version, 1),
598
471
  credentialId: requireMlsUuid(input.credentialId),
@@ -723,19 +596,21 @@ function parseMlsDevCredentialReceipt(value) {
723
596
  }
724
597
  __name(parseMlsDevCredentialReceipt, "parseMlsDevCredentialReceipt");
725
598
 
726
- // ../backend-contracts/src/mlsDevFeedReceipt.ts
727
- var MlsDevFeedReceiptValidationError = class extends Error {
599
+ // ../backend-contracts/src/mlsDevGroupFeed.ts
600
+ var MLS_DEV_GROUP_FEED_MAX_ENTRIES = 4;
601
+ var MLS_DEV_GROUP_FEED_MAX_BYTES = 4 * 1024 * 1024;
602
+ var MlsDevGroupFeedValidationError = class extends Error {
728
603
  static {
729
- __name(this, "MlsDevFeedReceiptValidationError");
604
+ __name(this, "MlsDevGroupFeedValidationError");
730
605
  }
731
- code = "INVALID_MLS_DEV_FEED_RECEIPT";
606
+ code = "INVALID_MLS_DEV_GROUP_FEED";
732
607
  constructor() {
733
- super("INVALID_MLS_DEV_FEED_RECEIPT");
734
- this.name = "MlsDevFeedReceiptValidationError";
608
+ super("INVALID_MLS_DEV_GROUP_FEED");
609
+ this.name = "MlsDevGroupFeedValidationError";
735
610
  }
736
611
  };
737
612
  function invalid4() {
738
- throw new MlsDevFeedReceiptValidationError();
613
+ throw new MlsDevGroupFeedValidationError();
739
614
  }
740
615
  __name(invalid4, "invalid");
741
616
  function boundary3(read) {
@@ -746,139 +621,89 @@ function boundary3(read) {
746
621
  }
747
622
  }
748
623
  __name(boundary3, "boundary");
749
- function parseMlsDevReceiptKeyVersion(value, environmentId) {
750
- return boundary3(() => {
751
- if (typeof value !== "string" || value.length > 200) invalid4();
752
- const owner = mlsEnvironmentOfReceiptKeyVersion(value);
753
- if (!owner || environmentId !== void 0 && owner !== environmentId) invalid4();
754
- return value;
755
- });
756
- }
757
- __name(parseMlsDevReceiptKeyVersion, "parseMlsDevReceiptKeyVersion");
758
- function parseMlsDevFeedReceiptProof(value) {
759
- return boundary3(() => {
760
- const input = readMlsDataRecord(value, ["keyVersion", "signature"]);
761
- decodeCanonicalMlsBase64Url(input.signature, 64);
762
- return Object.freeze({ keyVersion: parseMlsDevReceiptKeyVersion(input.keyVersion), signature: input.signature });
763
- });
764
- }
765
- __name(parseMlsDevFeedReceiptProof, "parseMlsDevFeedReceiptProof");
766
- var MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW = "MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW";
767
- function isMlsDevReceiptClockSkew(value) {
768
- if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
769
- const keys2 = Object.keys(value).sort().join(), input = value;
770
- return (keys2 === "error,ok,retryable" || keys2 === "error,ok,retryable,version" && input.version === 1) && input.ok === false && input.error === MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW && input.retryable === true;
771
- }
772
- __name(isMlsDevReceiptClockSkew, "isMlsDevReceiptClockSkew");
773
-
774
- // ../backend-contracts/src/mlsDevGroupFeed.ts
775
- var MLS_DEV_GROUP_FEED_MAX_ENTRIES = 4;
776
- var MLS_DEV_GROUP_FEED_MAX_BYTES = 4 * 1024 * 1024;
777
- var MlsDevGroupFeedValidationError = class extends Error {
778
- static {
779
- __name(this, "MlsDevGroupFeedValidationError");
780
- }
781
- code = "INVALID_MLS_DEV_GROUP_FEED";
782
- constructor() {
783
- super("INVALID_MLS_DEV_GROUP_FEED");
784
- this.name = "MlsDevGroupFeedValidationError";
785
- }
786
- };
787
- function invalid5() {
788
- throw new MlsDevGroupFeedValidationError();
789
- }
790
- __name(invalid5, "invalid");
791
- function boundary4(read) {
792
- try {
793
- return read();
794
- } catch {
795
- return invalid5();
796
- }
797
- }
798
- __name(boundary4, "boundary");
799
624
  function id(value) {
800
625
  if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..")
801
- invalid5();
626
+ invalid4();
802
627
  return value;
803
628
  }
804
629
  __name(id, "id");
805
630
  function boolean(value) {
806
631
  if (typeof value !== "boolean")
807
- invalid5();
632
+ invalid4();
808
633
  return value;
809
634
  }
810
635
  __name(boolean, "boolean");
811
636
  function bounded3(value) {
812
637
  if (new TextEncoder().encode(JSON.stringify(value)).length > MLS_DEV_GROUP_FEED_MAX_BYTES)
813
- invalid5();
638
+ invalid4();
814
639
  return Object.freeze(value);
815
640
  }
816
641
  __name(bounded3, "bounded");
817
642
  function array(value) {
818
643
  if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || value.length > MLS_DEV_GROUP_FEED_MAX_ENTRIES)
819
- invalid5();
644
+ invalid4();
820
645
  const descriptors = Object.getOwnPropertyDescriptors(value);
821
646
  if (Reflect.ownKeys(descriptors).length !== value.length + 1)
822
- invalid5();
647
+ invalid4();
823
648
  return Array.from({ length: value.length }, (_, index) => {
824
649
  const field = descriptors[index];
825
650
  if (!field || !field.enumerable || !Object.hasOwn(field, "value"))
826
- invalid5();
651
+ invalid4();
827
652
  return field.value;
828
653
  });
829
654
  }
830
655
  __name(array, "array");
831
656
  function parseMlsDevGroupFeedEntry(value) {
832
- return boundary4(() => {
657
+ return boundary3(() => {
833
658
  const signed = value !== null && typeof value === "object" && Object.hasOwn(value, "receiptProof") ? ["receiptProof"] : [];
834
659
  const input = readMlsDataRecord(value, ["version", "ordinal", "kind", "accepted", ...signed], ["version", "ordinal", "kind", "receipt", "envelope", ...signed]);
835
660
  const version = requireMlsLiteral(input.version, 1), ordinal = requireMlsInteger(input.ordinal, 1);
836
661
  const proof = signed.length ? { receiptProof: parseMlsDevFeedReceiptProof(input.receiptProof) } : {};
837
662
  if (input.kind === "control") {
838
663
  if (!Object.hasOwn(input, "accepted"))
839
- invalid5();
664
+ invalid4();
840
665
  return bounded3({ version, ordinal, kind: "control", accepted: parseMlsDevGroupAcceptedControl(input.accepted), ...proof });
841
666
  }
842
667
  const kind = requireMlsLiteral(input.kind, "application"), receipt = parseMlsDevApplicationReceipt(input.receipt), envelope = parseMlsDevApplicationEnvelope(input.envelope);
843
668
  if (ordinal !== receipt.feedOrdinal || receipt.conversationId !== envelope.conversationId || receipt.groupId !== envelope.groupId || receipt.messageId !== envelope.messageId || JSON.stringify(receipt.head) !== JSON.stringify(envelope.expectedHead))
844
- invalid5();
669
+ invalid4();
845
670
  return bounded3({ version, ordinal, kind, receipt, envelope, ...proof });
846
671
  });
847
672
  }
848
673
  __name(parseMlsDevGroupFeedEntry, "parseMlsDevGroupFeedEntry");
849
674
  function parseMlsDevGroupFeedQuery(value) {
850
- return boundary4(() => {
675
+ return boundary3(() => {
851
676
  const input = readMlsDataRecord(value, ["version", "conversationId", "credential", "afterOrdinal", "limit"]);
852
677
  const limit2 = requireMlsInteger(input.limit, 1);
853
678
  if (limit2 > MLS_DEV_GROUP_FEED_MAX_ENTRIES)
854
- invalid5();
679
+ invalid4();
855
680
  parseMlsDevCredentialToken(input.credential);
856
681
  return Object.freeze({ version: requireMlsLiteral(input.version, 1), conversationId: id(input.conversationId), credential: input.credential, afterOrdinal: requireMlsInteger(input.afterOrdinal), limit: limit2 });
857
682
  });
858
683
  }
859
684
  __name(parseMlsDevGroupFeedQuery, "parseMlsDevGroupFeedQuery");
860
685
  function parseMlsDevGroupFeedResult(value) {
861
- return boundary4(() => {
686
+ return boundary3(() => {
862
687
  const input = readMlsDataRecord(value, ["version", "protocol", "conversationId", "marker", "membershipRevision", "admissionId", "roster", "minimumOrdinal", "latestOrdinal", "nextOrdinal", "entries", "hasMore", "terminal"]);
863
688
  const conversationId = id(input.conversationId), marker = input.marker === null ? null : parseMlsDevGroupMarker(input.marker);
864
689
  const minimumOrdinal = input.minimumOrdinal === null ? null : requireMlsInteger(input.minimumOrdinal, 1);
865
690
  const latestOrdinal = requireMlsInteger(input.latestOrdinal), nextOrdinal = requireMlsInteger(input.nextOrdinal);
866
691
  const entries = array(input.entries).map(parseMlsDevGroupFeedEntry), hasMore = boolean(input.hasMore), terminal = boolean(input.terminal);
867
692
  if (nextOrdinal > latestOrdinal || minimumOrdinal !== null && minimumOrdinal > latestOrdinal || minimumOrdinal === null && (entries.length || nextOrdinal || hasMore || terminal) || !marker && (latestOrdinal || minimumOrdinal !== null || entries.length || terminal))
868
- invalid5();
869
- const protocol = isMlsDevTextProtocol(input.protocol) ? input.protocol : invalid5();
693
+ invalid4();
694
+ const protocol = isMlsDevTextProtocol(input.protocol) ? input.protocol : invalid4();
870
695
  for (let i = 0; i < entries.length; i++) {
871
696
  const entry = entries[i], subject = entry.kind === "control" ? entry.accepted.control : entry.envelope;
872
697
  if (entry.kind === "application" && entry.envelope.interaction && !mlsDevProtocolCarriesCards(protocol))
873
- invalid5();
698
+ invalid4();
874
699
  if (!marker || minimumOrdinal === null || entry.ordinal < minimumOrdinal || entry.ordinal > latestOrdinal || subject.conversationId !== conversationId || subject.groupId !== marker.groupId || i > 0 && entry.ordinal !== entries[i - 1].ordinal + 1)
875
- invalid5();
700
+ invalid4();
876
701
  const head = entry.kind === "control" ? entry.accepted.head : entry.receipt.head;
877
702
  if (head.sequence > marker.head.sequence || head.epoch > marker.head.epoch)
878
- invalid5();
703
+ invalid4();
879
704
  }
880
705
  if (entries.length && entries.at(-1).ordinal !== nextOrdinal || hasMore !== (minimumOrdinal !== null && nextOrdinal < latestOrdinal))
881
- invalid5();
706
+ invalid4();
882
707
  return bounded3({
883
708
  version: requireMlsLiteral(input.version, 1),
884
709
  protocol,
@@ -911,25 +736,25 @@ var MlsDevKeyPackagesValidationError = class extends Error {
911
736
  this.name = "MlsDevKeyPackagesValidationError";
912
737
  }
913
738
  };
914
- function invalid6() {
739
+ function invalid5() {
915
740
  throw new MlsDevKeyPackagesValidationError();
916
741
  }
917
- __name(invalid6, "invalid");
918
- function boundary5(read) {
742
+ __name(invalid5, "invalid");
743
+ function boundary4(read) {
919
744
  try {
920
745
  return read();
921
746
  } catch {
922
- return invalid6();
747
+ return invalid5();
923
748
  }
924
749
  }
925
- __name(boundary5, "boundary");
750
+ __name(boundary4, "boundary");
926
751
  function bounded4(value) {
927
- if (new TextEncoder().encode(JSON.stringify(value)).length > MLS_DEV_KEY_PACKAGES_MAX_BYTES) invalid6();
752
+ if (new TextEncoder().encode(JSON.stringify(value)).length > MLS_DEV_KEY_PACKAGES_MAX_BYTES) invalid5();
928
753
  return Object.freeze(value);
929
754
  }
930
755
  __name(bounded4, "bounded");
931
756
  function id2(value) {
932
- if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..") invalid6();
757
+ if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..") invalid5();
933
758
  return value;
934
759
  }
935
760
  __name(id2, "id");
@@ -939,18 +764,18 @@ function ref(value) {
939
764
  }
940
765
  __name(ref, "ref");
941
766
  function parseMlsDevKeyPackageWire(value) {
942
- return boundary5(() => {
943
- if (typeof value !== "string" || value.length < 2 || value.length > Math.ceil(MLS_DEV_KEY_PACKAGE_TLS_MAX_BYTES * 4 / 3)) invalid6();
767
+ return boundary4(() => {
768
+ if (typeof value !== "string" || value.length < 2 || value.length > Math.ceil(MLS_DEV_KEY_PACKAGE_TLS_MAX_BYTES * 4 / 3)) invalid5();
944
769
  const bytes = Math.floor(value.length * 3 / 4);
945
- if (bytes < 1 || bytes > MLS_DEV_KEY_PACKAGE_TLS_MAX_BYTES || value.length !== Math.ceil(bytes * 4 / 3) || !/^[A-Za-z0-9_-]+$/.test(value)) invalid6();
770
+ if (bytes < 1 || bytes > MLS_DEV_KEY_PACKAGE_TLS_MAX_BYTES || value.length !== Math.ceil(bytes * 4 / 3) || !/^[A-Za-z0-9_-]+$/.test(value)) invalid5();
946
771
  const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
947
- if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0) invalid6();
772
+ if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0) invalid5();
948
773
  return value;
949
774
  });
950
775
  }
951
776
  __name(parseMlsDevKeyPackageWire, "parseMlsDevKeyPackageWire");
952
777
  function parseMlsDevKeyPackageClaimPreconditions(value) {
953
- return boundary5(() => {
778
+ return boundary4(() => {
954
779
  const input = readMlsDataRecord(value, ["conversationId", "membershipRevision", "admissionId", "targetAdmissionId"]);
955
780
  return Object.freeze({
956
781
  conversationId: id2(input.conversationId),
@@ -962,17 +787,17 @@ function parseMlsDevKeyPackageClaimPreconditions(value) {
962
787
  }
963
788
  __name(parseMlsDevKeyPackageClaimPreconditions, "parseMlsDevKeyPackageClaimPreconditions");
964
789
  function parseMlsDevKeyPackagePublish(value) {
965
- return boundary5(() => {
790
+ return boundary4(() => {
966
791
  const input = readMlsDataRecord(value, ["version", "requestId", "keyPackage"]);
967
792
  return bounded4({ version: requireMlsLiteral(input.version, 1), requestId: requireMlsUuid(input.requestId), keyPackage: parseMlsDevKeyPackageWire(input.keyPackage) });
968
793
  });
969
794
  }
970
795
  __name(parseMlsDevKeyPackagePublish, "parseMlsDevKeyPackagePublish");
971
796
  function parseMlsDevKeyPackagePublicationReceipt(value) {
972
- return boundary5(() => {
797
+ return boundary4(() => {
973
798
  const input = readMlsDataRecord(value, ["version", "authorization", "requestId", "keyPackageRef", "deviceId", "publishedAtMs", "expiresAtMs"]);
974
799
  const publishedAtMs = requireMlsInteger(input.publishedAtMs), expiresAtMs = requireMlsInteger(input.expiresAtMs);
975
- if (publishedAtMs >= expiresAtMs) invalid6();
800
+ if (publishedAtMs >= expiresAtMs) invalid5();
976
801
  return bounded4({
977
802
  version: requireMlsLiteral(input.version, 1),
978
803
  authorization: requireMlsLiteral(input.authorization, "key_package_publication_only"),
@@ -986,7 +811,7 @@ function parseMlsDevKeyPackagePublicationReceipt(value) {
986
811
  }
987
812
  __name(parseMlsDevKeyPackagePublicationReceipt, "parseMlsDevKeyPackagePublicationReceipt");
988
813
  function parseMlsDevKeyPackageClaim(value) {
989
- return boundary5(() => {
814
+ return boundary4(() => {
990
815
  const input = readMlsDataRecord(value, ["version", "requestId", "claimantCredential", "recipientDeviceId", "preconditions"]);
991
816
  parseMlsDevCredentialToken(input.claimantCredential);
992
817
  return bounded4({
@@ -1000,7 +825,7 @@ function parseMlsDevKeyPackageClaim(value) {
1000
825
  }
1001
826
  __name(parseMlsDevKeyPackageClaim, "parseMlsDevKeyPackageClaim");
1002
827
  function parseMlsDevKeyPackageClaimReceipt(value) {
1003
- return boundary5(() => {
828
+ return boundary4(() => {
1004
829
  const input = readMlsDataRecord(value, [
1005
830
  "version",
1006
831
  "authorization",
@@ -1013,7 +838,7 @@ function parseMlsDevKeyPackageClaimReceipt(value) {
1013
838
  "claimedAtMs"
1014
839
  ]);
1015
840
  const claimantDeviceId = requireMlsUuid(input.claimantDeviceId), recipientDeviceId = requireMlsUuid(input.recipientDeviceId);
1016
- if (claimantDeviceId === recipientDeviceId) invalid6();
841
+ if (claimantDeviceId === recipientDeviceId) invalid5();
1017
842
  return bounded4({
1018
843
  version: requireMlsLiteral(input.version, 1),
1019
844
  authorization: requireMlsLiteral(input.authorization, "key_package_claim_only"),
@@ -1044,25 +869,25 @@ var MlsDevInteractionValidationError = class extends Error {
1044
869
  }
1045
870
  };
1046
871
  var utf83 = new TextEncoder();
1047
- function invalid7() {
872
+ function invalid6() {
1048
873
  throw new MlsDevInteractionValidationError();
1049
874
  }
1050
- __name(invalid7, "invalid");
1051
- function boundary6(read) {
875
+ __name(invalid6, "invalid");
876
+ function boundary5(read) {
1052
877
  try {
1053
878
  return read();
1054
879
  } catch {
1055
- return invalid7();
880
+ return invalid6();
1056
881
  }
1057
882
  }
1058
- __name(boundary6, "boundary");
883
+ __name(boundary5, "boundary");
1059
884
  function id3(value) {
1060
- if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..") invalid7();
885
+ if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..") invalid6();
1061
886
  return value;
1062
887
  }
1063
888
  __name(id3, "id");
1064
889
  function interactionId(value) {
1065
- if (typeof value !== "string" || !MLS_DEV_INTERACTION_ID_PATTERN.test(value) || value === "." || value === "..") invalid7();
890
+ if (typeof value !== "string" || !MLS_DEV_INTERACTION_ID_PATTERN.test(value) || value === "." || value === "..") invalid6();
1066
891
  return value;
1067
892
  }
1068
893
  __name(interactionId, "interactionId");
@@ -1072,39 +897,39 @@ function encoded3(value, bytes) {
1072
897
  }
1073
898
  __name(encoded3, "encoded");
1074
899
  function wire(value, min, max) {
1075
- if (typeof value !== "string" || !/^[A-Za-z0-9_-]*$/.test(value) || value.length % 4 === 1) invalid7();
900
+ if (typeof value !== "string" || !/^[A-Za-z0-9_-]*$/.test(value) || value.length % 4 === 1) invalid6();
1076
901
  const bytes = Math.floor(value.length * 3 / 4);
1077
- if (bytes < min || bytes > max) invalid7();
902
+ if (bytes < min || bytes > max) invalid6();
1078
903
  const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
1079
- if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0) invalid7();
904
+ if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0) invalid6();
1080
905
  return value;
1081
906
  }
1082
907
  __name(wire, "wire");
1083
908
  function text(value, max) {
1084
- if (typeof value !== "string" || !value.trim() || [...value].length > max || new TextDecoder("utf-8", { fatal: true }).decode(utf83.encode(value)) !== value) invalid7();
909
+ if (typeof value !== "string" || !value.trim() || [...value].length > max || new TextDecoder("utf-8", { fatal: true }).decode(utf83.encode(value)) !== value) invalid6();
1085
910
  return value;
1086
911
  }
1087
912
  __name(text, "text");
1088
913
  function boolean2(value) {
1089
- if (typeof value !== "boolean") invalid7();
914
+ if (typeof value !== "boolean") invalid6();
1090
915
  return value;
1091
916
  }
1092
917
  __name(boolean2, "boolean");
1093
918
  function array2(value, min, max) {
1094
- if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || value.length < min || value.length > max) invalid7();
919
+ if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || value.length < min || value.length > max) invalid6();
1095
920
  const descriptors = Object.getOwnPropertyDescriptors(value);
1096
- if (Reflect.ownKeys(descriptors).length !== value.length + 1) invalid7();
921
+ if (Reflect.ownKeys(descriptors).length !== value.length + 1) invalid6();
1097
922
  return Array.from({ length: value.length }, (_, index) => {
1098
923
  const field = descriptors[index];
1099
- if (!field || !field.enumerable || !Object.hasOwn(field, "value")) invalid7();
924
+ if (!field || !field.enumerable || !Object.hasOwn(field, "value")) invalid6();
1100
925
  return field.value;
1101
926
  });
1102
927
  }
1103
928
  __name(array2, "array");
1104
929
  function closed(value, required, optional) {
1105
- if (value === null || typeof value !== "object" || Array.isArray(value)) invalid7();
930
+ if (value === null || typeof value !== "object" || Array.isArray(value)) invalid6();
1106
931
  const present2 = Reflect.ownKeys(value);
1107
- if (present2.some((key) => typeof key !== "string" || !required.includes(key) && !optional.includes(key))) invalid7();
932
+ if (present2.some((key) => typeof key !== "string" || !required.includes(key) && !optional.includes(key))) invalid6();
1108
933
  return readMlsDataRecord(value, present2);
1109
934
  }
1110
935
  __name(closed, "closed");
@@ -1113,31 +938,31 @@ function ordered(value) {
1113
938
  }
1114
939
  __name(ordered, "ordered");
1115
940
  function parseMlsDevInteractionRequestBody(value) {
1116
- return boundary6(() => {
941
+ return boundary5(() => {
1117
942
  const input = closed(
1118
943
  value,
1119
944
  ["requestId", "kind", "title", "responderIds", "expiresAtMs"],
1120
945
  ["details", "options", "multiple", "risk", "allowSession", "scopeKey", "secretKey"]
1121
946
  );
1122
947
  const kind = input.kind;
1123
- if (typeof kind !== "string" || !MLS_DEV_INTERACTION_KINDS.includes(kind)) invalid7();
948
+ if (typeof kind !== "string" || !MLS_DEV_INTERACTION_KINDS.includes(kind)) invalid6();
1124
949
  const has = /* @__PURE__ */ __name((key) => Object.hasOwn(input, key), "has");
1125
950
  const options = has("options") ? array2(input.options, 1, MLS_DEV_INTERACTION_LIMITS.options).map((option) => {
1126
951
  const fields2 = readMlsDataRecord(option, ["id", "label"]);
1127
- if (typeof fields2.id !== "string" || !/^[A-Za-z0-9_.:-]{1,64}$/.test(fields2.id)) invalid7();
952
+ if (typeof fields2.id !== "string" || !/^[A-Za-z0-9_.:-]{1,64}$/.test(fields2.id)) invalid6();
1128
953
  return Object.freeze({ id: fields2.id, label: text(fields2.label, MLS_DEV_INTERACTION_LIMITS.optionLabel) });
1129
954
  }) : void 0;
1130
- if (options && new Set(options.map((option) => option.id)).size !== options.length) invalid7();
955
+ if (options && new Set(options.map((option) => option.id)).size !== options.length) invalid6();
1131
956
  const binding3 = parseMlsDevInteractionBinding({ role: "request", requestId: input.requestId, kind, responderIds: input.responderIds, expiresAtMs: input.expiresAtMs });
1132
- if (binding3.role !== "request") invalid7();
1133
- if (kind !== "approval" && ["risk", "allowSession", "scopeKey"].some(has)) invalid7();
1134
- if (kind !== "question" && (has("options") || has("multiple"))) invalid7();
1135
- if (has("multiple") && !options) invalid7();
1136
- if (kind === "secret" !== has("secretKey")) invalid7();
957
+ if (binding3.role !== "request") invalid6();
958
+ if (kind !== "approval" && ["risk", "allowSession", "scopeKey"].some(has)) invalid6();
959
+ if (kind !== "question" && (has("options") || has("multiple"))) invalid6();
960
+ if (has("multiple") && !options) invalid6();
961
+ if (kind === "secret" !== has("secretKey")) invalid6();
1137
962
  const allowSession = has("allowSession") ? boolean2(input.allowSession) : void 0;
1138
- if (has("scopeKey") && (typeof input.scopeKey !== "string" || !/^[A-Za-z0-9_:-]{1,64}$/.test(input.scopeKey))) invalid7();
1139
- if (allowSession === true && !has("scopeKey")) invalid7();
1140
- if (has("risk") && input.risk !== "normal" && input.risk !== "destructive") invalid7();
963
+ if (has("scopeKey") && (typeof input.scopeKey !== "string" || !/^[A-Za-z0-9_:-]{1,64}$/.test(input.scopeKey))) invalid6();
964
+ if (allowSession === true && !has("scopeKey")) invalid6();
965
+ if (has("risk") && input.risk !== "normal" && input.risk !== "destructive") invalid6();
1141
966
  const secretKey = has("secretKey") ? (() => {
1142
967
  const key = readMlsDataRecord(input.secretKey, ["kem", "publicKey"]);
1143
968
  return Object.freeze({ kem: requireMlsLiteral(key.kem, "x25519"), publicKey: encoded3(key.publicKey, 32) });
@@ -1160,20 +985,20 @@ function parseMlsDevInteractionRequestBody(value) {
1160
985
  }
1161
986
  __name(parseMlsDevInteractionRequestBody, "parseMlsDevInteractionRequestBody");
1162
987
  function parseMlsDevInteractionAnswer(value) {
1163
- return boundary6(() => {
1164
- if (value === null || typeof value !== "object" || Array.isArray(value)) invalid7();
988
+ return boundary5(() => {
989
+ if (value === null || typeof value !== "object" || Array.isArray(value)) invalid6();
1165
990
  const keys2 = Reflect.ownKeys(value);
1166
991
  if (keys2.includes("decision")) {
1167
992
  const input = readMlsDataRecord(value, ["decision", "scope"]);
1168
- if (input.decision !== "allow" && input.decision !== "deny" || input.scope !== "once" && input.scope !== "session") invalid7();
993
+ if (input.decision !== "allow" && input.decision !== "deny" || input.scope !== "once" && input.scope !== "session") invalid6();
1169
994
  return Object.freeze({ decision: input.decision, scope: input.scope });
1170
995
  }
1171
996
  if (keys2.includes("choices")) {
1172
997
  const choices = array2(readMlsDataRecord(value, ["choices"]).choices, 1, MLS_DEV_INTERACTION_LIMITS.options).map((choice) => {
1173
- if (typeof choice !== "string" || !/^[A-Za-z0-9_.:-]{1,64}$/.test(choice)) invalid7();
998
+ if (typeof choice !== "string" || !/^[A-Za-z0-9_.:-]{1,64}$/.test(choice)) invalid6();
1174
999
  return choice;
1175
1000
  });
1176
- if (new Set(choices).size !== choices.length) invalid7();
1001
+ if (new Set(choices).size !== choices.length) invalid6();
1177
1002
  return Object.freeze({ choices: Object.freeze(choices) });
1178
1003
  }
1179
1004
  if (keys2.includes("text")) return Object.freeze({ text: text(readMlsDataRecord(value, ["text"]).text, MLS_DEV_INTERACTION_LIMITS.text) });
@@ -1181,31 +1006,31 @@ function parseMlsDevInteractionAnswer(value) {
1181
1006
  const sealed = readMlsDataRecord(readMlsDataRecord(value, ["sealed"]).sealed, ["enc", "ciphertext"]);
1182
1007
  return Object.freeze({ sealed: Object.freeze({ enc: encoded3(sealed.enc, 32), ciphertext: wire(sealed.ciphertext, 17, MLS_DEV_SECRET_ANSWER_MAX_BYTES) }) });
1183
1008
  }
1184
- if (readMlsDataRecord(value, ["cancelled"]).cancelled !== true) invalid7();
1009
+ if (readMlsDataRecord(value, ["cancelled"]).cancelled !== true) invalid6();
1185
1010
  return Object.freeze({ cancelled: true });
1186
1011
  });
1187
1012
  }
1188
1013
  __name(parseMlsDevInteractionAnswer, "parseMlsDevInteractionAnswer");
1189
1014
  function parseMlsDevInteractionResponseBody(value) {
1190
- return boundary6(() => {
1015
+ return boundary5(() => {
1191
1016
  const input = readMlsDataRecord(value, ["requestId", "agentId", "answer"]);
1192
1017
  return Object.freeze({ requestId: interactionId(input.requestId), agentId: id3(input.agentId), answer: parseMlsDevInteractionAnswer(input.answer) });
1193
1018
  });
1194
1019
  }
1195
1020
  __name(parseMlsDevInteractionResponseBody, "parseMlsDevInteractionResponseBody");
1196
1021
  function parseMlsDevInteractionWithdrawBody(value) {
1197
- return boundary6(() => {
1022
+ return boundary5(() => {
1198
1023
  const input = readMlsDataRecord(value, ["requestId", "reason"]);
1199
- if (!MLS_DEV_INTERACTION_WITHDRAW_REASONS.includes(input.reason)) invalid7();
1024
+ if (!MLS_DEV_INTERACTION_WITHDRAW_REASONS.includes(input.reason)) invalid6();
1200
1025
  return Object.freeze({ requestId: interactionId(input.requestId), reason: input.reason });
1201
1026
  });
1202
1027
  }
1203
1028
  __name(parseMlsDevInteractionWithdrawBody, "parseMlsDevInteractionWithdrawBody");
1204
1029
  var payloadFields = ["version", "kind", "conversationId", "groupId", "messageId", "operationId", "senderDeviceId"];
1205
1030
  function parseMlsDevApplicationPayload(value) {
1206
- return boundary6(() => {
1031
+ return boundary5(() => {
1207
1032
  const kind = value && typeof value === "object" ? Object.getOwnPropertyDescriptor(value, "kind") : void 0;
1208
- if (!kind || !Object.hasOwn(kind, "value")) invalid7();
1033
+ if (!kind || !Object.hasOwn(kind, "value")) invalid6();
1209
1034
  if (kind.value === "text") return parseMlsDevTextPayload(value);
1210
1035
  if (kind.value === "item") return parseMlsDevItemPayload(value);
1211
1036
  const input = readMlsDataRecord(value, [...payloadFields, "interaction"]);
@@ -1218,26 +1043,26 @@ function parseMlsDevApplicationPayload(value) {
1218
1043
  operationId: id3(input.operationId),
1219
1044
  senderDeviceId: requireMlsUuid(input.senderDeviceId)
1220
1045
  };
1221
- if (ids.messageId.startsWith("membership-")) invalid7();
1222
- const interaction = kind.value === "interaction.request" ? parseMlsDevInteractionRequestBody(input.interaction) : kind.value === "interaction.response" ? parseMlsDevInteractionResponseBody(input.interaction) : kind.value === "interaction.withdraw" ? parseMlsDevInteractionWithdrawBody(input.interaction) : invalid7();
1046
+ if (ids.messageId.startsWith("membership-")) invalid6();
1047
+ const interaction = kind.value === "interaction.request" ? parseMlsDevInteractionRequestBody(input.interaction) : kind.value === "interaction.response" ? parseMlsDevInteractionResponseBody(input.interaction) : kind.value === "interaction.withdraw" ? parseMlsDevInteractionWithdrawBody(input.interaction) : invalid6();
1223
1048
  const payload = Object.freeze({ ...ids, interaction });
1224
- if (utf83.encode(JSON.stringify(payload)).length > MLS_DEV_TEXT_MAX_BYTES) invalid7();
1049
+ if (utf83.encode(JSON.stringify(payload)).length > MLS_DEV_TEXT_MAX_BYTES) invalid6();
1225
1050
  return payload;
1226
1051
  });
1227
1052
  }
1228
1053
  __name(parseMlsDevApplicationPayload, "parseMlsDevApplicationPayload");
1229
1054
  function assertMlsDevInteractionPayloadBinding(payload, binding3) {
1230
- boundary6(() => {
1055
+ boundary5(() => {
1231
1056
  if (payload.kind === "text" || payload.kind === "item") {
1232
- if (binding3 !== void 0) invalid7();
1057
+ if (binding3 !== void 0) invalid6();
1233
1058
  return;
1234
1059
  }
1235
- if (!binding3 || payload.interaction.requestId !== binding3.requestId) invalid7();
1060
+ if (!binding3 || payload.interaction.requestId !== binding3.requestId) invalid6();
1236
1061
  if (payload.kind === "interaction.request") {
1237
- if (binding3.role !== "request" || payload.interaction.kind !== binding3.kind || payload.interaction.expiresAtMs !== binding3.expiresAtMs || payload.interaction.responderIds.length !== 1 || payload.interaction.responderIds[0] !== binding3.responderIds[0]) invalid7();
1062
+ if (binding3.role !== "request" || payload.interaction.kind !== binding3.kind || payload.interaction.expiresAtMs !== binding3.expiresAtMs || payload.interaction.responderIds.length !== 1 || payload.interaction.responderIds[0] !== binding3.responderIds[0]) invalid6();
1238
1063
  } else if (payload.kind === "interaction.response") {
1239
- if (binding3.role !== "response" || payload.interaction.agentId !== binding3.agentId) invalid7();
1240
- } else if (binding3.role !== "withdraw") invalid7();
1064
+ if (binding3.role !== "response" || payload.interaction.agentId !== binding3.agentId) invalid6();
1065
+ } else if (binding3.role !== "withdraw") invalid6();
1241
1066
  });
1242
1067
  }
1243
1068
  __name(assertMlsDevInteractionPayloadBinding, "assertMlsDevInteractionPayloadBinding");
@@ -1271,27 +1096,27 @@ var MlsDevGroupValidationError = class extends Error {
1271
1096
  }
1272
1097
  };
1273
1098
  var utf84 = new TextEncoder();
1274
- function invalid8() {
1099
+ function invalid7() {
1275
1100
  throw new MlsDevGroupValidationError();
1276
1101
  }
1277
- __name(invalid8, "invalid");
1278
- function boundary7(read) {
1102
+ __name(invalid7, "invalid");
1103
+ function boundary6(read) {
1279
1104
  try {
1280
1105
  return read();
1281
1106
  } catch {
1282
- return invalid8();
1107
+ return invalid7();
1283
1108
  }
1284
1109
  }
1285
- __name(boundary7, "boundary");
1110
+ __name(boundary6, "boundary");
1286
1111
  function bounded5(value, maximum = MLS_DEV_GROUP_CONTROL_MAX_BYTES) {
1287
1112
  if (utf84.encode(JSON.stringify(value)).length > maximum)
1288
- invalid8();
1113
+ invalid7();
1289
1114
  return Object.freeze(value);
1290
1115
  }
1291
1116
  __name(bounded5, "bounded");
1292
1117
  function id4(value) {
1293
1118
  if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..")
1294
- invalid8();
1119
+ invalid7();
1295
1120
  return value;
1296
1121
  }
1297
1122
  __name(id4, "id");
@@ -1302,13 +1127,13 @@ function encoded4(value, bytes) {
1302
1127
  __name(encoded4, "encoded");
1303
1128
  function boolean3(value) {
1304
1129
  if (typeof value !== "boolean")
1305
- invalid8();
1130
+ invalid7();
1306
1131
  return value;
1307
1132
  }
1308
1133
  __name(boolean3, "boolean");
1309
1134
  function textProtocol(value) {
1310
1135
  if (!isMlsDevTextProtocol(value))
1311
- invalid8();
1136
+ invalid7();
1312
1137
  return value;
1313
1138
  }
1314
1139
  __name(textProtocol, "textProtocol");
@@ -1319,19 +1144,19 @@ function token(value) {
1319
1144
  __name(token, "token");
1320
1145
  function wire2(value) {
1321
1146
  if (typeof value !== "string" || value.length < 2 || value.length > Math.ceil(MLS_DEV_GROUP_TLS_MAX_BYTES * 4 / 3))
1322
- invalid8();
1147
+ invalid7();
1323
1148
  const bytes = Math.floor(value.length * 3 / 4);
1324
1149
  if (value.length !== Math.ceil(bytes * 4 / 3) || !/^[A-Za-z0-9_-]+$/.test(value))
1325
- invalid8();
1150
+ invalid7();
1326
1151
  const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
1327
1152
  if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0)
1328
- invalid8();
1153
+ invalid7();
1329
1154
  return value;
1330
1155
  }
1331
1156
  __name(wire2, "wire");
1332
1157
  function plaintextJson(value) {
1333
1158
  if (typeof value !== "string" || !value || utf84.encode(value).length > MLS_DEV_TEXT_MAX_BYTES || new TextDecoder("utf-8", { fatal: true }).decode(utf84.encode(value)) !== value)
1334
- invalid8();
1159
+ invalid7();
1335
1160
  return value;
1336
1161
  }
1337
1162
  __name(plaintextJson, "plaintextJson");
@@ -1342,92 +1167,100 @@ __name(present, "present");
1342
1167
  var pick = /* @__PURE__ */ __name((value, keys2) => Object.fromEntries(keys2.map((key) => [key, value[key]])), "pick");
1343
1168
  var textExtras = /* @__PURE__ */ __name((text5) => ({ ...text5.replyTo ? { replyTo: text5.replyTo } : {}, ...text5.mentions ? { mentions: text5.mentions } : {} }), "textExtras");
1344
1169
  function sealedCiphertext(value) {
1345
- if (typeof value !== "string" || !/^[A-Za-z0-9_-]+$/.test(value) || value.length % 4 === 1) invalid8();
1170
+ if (typeof value !== "string" || !/^[A-Za-z0-9_-]+$/.test(value) || value.length % 4 === 1) invalid7();
1346
1171
  const bytes = Math.floor(value.length * 3 / 4);
1347
- if (bytes < 17 || bytes > MLS_DEV_SECRET_ANSWER_MAX_BYTES) invalid8();
1172
+ if (bytes < 17 || bytes > MLS_DEV_SECRET_ANSWER_MAX_BYTES) invalid7();
1348
1173
  const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
1349
- if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0) invalid8();
1174
+ if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0) invalid7();
1350
1175
  return value;
1351
1176
  }
1352
1177
  __name(sealedCiphertext, "sealedCiphertext");
1353
1178
  function array3(value, maximum) {
1354
1179
  if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || value.length > maximum)
1355
- invalid8();
1180
+ invalid7();
1356
1181
  const descriptors = Object.getOwnPropertyDescriptors(value);
1357
1182
  if (Reflect.ownKeys(descriptors).length !== value.length + 1)
1358
- invalid8();
1183
+ invalid7();
1359
1184
  return Array.from({ length: value.length }, (_, index) => {
1360
1185
  const descriptor = descriptors[index];
1361
1186
  if (!descriptor || !descriptor.enumerable || !Object.hasOwn(descriptor, "value"))
1362
- invalid8();
1187
+ invalid7();
1363
1188
  return descriptor.value;
1364
1189
  });
1365
1190
  }
1366
1191
  __name(array3, "array");
1367
1192
  function parseMlsDevGroupCreateConversation(value) {
1368
- return boundary7(() => {
1193
+ return boundary6(() => {
1369
1194
  const input = readMlsDataRecord(value, ["name", "memberIds", "mlsDev"]), config = readMlsDataRecord(input.mlsDev, ["version", "conversationId", "credential"], ["version", "conversationId", "credential", "protocol"]);
1370
1195
  if (typeof input.name !== "string" || input.name.trim().length > 100)
1371
- invalid8();
1196
+ invalid7();
1372
1197
  const memberIds = array3(input.memberIds, 31).map((value2) => parseMlsDevEnrollmentPrincipal({ type: "human", id: value2 }).id);
1373
1198
  if (!memberIds.length || new Set(memberIds).size !== memberIds.length || memberIds.some((value2) => value2.includes("/") || value2 === "." || value2 === ".."))
1374
- invalid8();
1199
+ invalid7();
1375
1200
  return bounded5({ name: input.name, memberIds: Object.freeze(memberIds), mlsDev: Object.freeze({ version: requireMlsLiteral(config.version, 1), conversationId: id4(config.conversationId), credential: token(config.credential), ...Object.hasOwn(config, "protocol") ? { protocol: textProtocol(config.protocol) } : {} }) }, 16 * 1024);
1376
1201
  });
1377
1202
  }
1378
1203
  __name(parseMlsDevGroupCreateConversation, "parseMlsDevGroupCreateConversation");
1379
1204
  function parseMlsDevGroupHead(value) {
1380
- return boundary7(() => {
1205
+ return boundary6(() => {
1381
1206
  const input = readMlsDataRecord(value, ["sequence", "epoch", "hash"]);
1382
1207
  return Object.freeze({ sequence: requireMlsInteger(input.sequence, 1), epoch: requireMlsInteger(input.epoch), hash: encoded4(input.hash, 32) });
1383
1208
  });
1384
1209
  }
1385
1210
  __name(parseMlsDevGroupHead, "parseMlsDevGroupHead");
1386
1211
  function parseMlsDevGroupMarker(value) {
1387
- return boundary7(() => {
1212
+ return boundary6(() => {
1388
1213
  const input = readMlsDataRecord(value, ["version", "groupId", "head"]);
1389
1214
  return Object.freeze({ version: requireMlsLiteral(input.version, 1), groupId: encoded4(input.groupId, 32), head: parseMlsDevGroupHead(input.head) });
1390
1215
  });
1391
1216
  }
1392
1217
  __name(parseMlsDevGroupMarker, "parseMlsDevGroupMarker");
1393
1218
  function parseMlsDevGroupRoster(value) {
1394
- return boundary7(() => {
1219
+ return boundary6(() => {
1395
1220
  const values = array3(value, MLS_DEV_GROUP_ROSTER_MAX).map((item2) => {
1396
1221
  const entry = readMlsDataRecord(item2, ["device", "admissionId"]);
1397
1222
  return Object.freeze({ device: parseMlsDevEnrollmentResult({ version: 1, authorization: "registration_only", device: entry.device }).device, admissionId: id4(entry.admissionId) });
1398
1223
  });
1399
1224
  for (let i = 1; i < values.length; i++)
1400
1225
  if (values[i - 1].device.deviceId >= values[i].device.deviceId)
1401
- invalid8();
1226
+ invalid7();
1402
1227
  return Object.freeze(values);
1403
1228
  });
1404
1229
  }
1405
1230
  __name(parseMlsDevGroupRoster, "parseMlsDevGroupRoster");
1231
+ var MLS_MEMBER_JOIN_WAIT_MS = 6e4;
1232
+ function mlsAdmissionWait(input) {
1233
+ const { senderId, memberIds, admitted } = input;
1234
+ const expected = [.../* @__PURE__ */ new Set([...memberIds, ...input.unacceptedIds])];
1235
+ if (!expected.some((id7) => id7 !== senderId && admitted.has(id7))) return expected.filter((id7) => !admitted.has(id7));
1236
+ return input.nowMs < input.joinedAtMs + MLS_MEMBER_JOIN_WAIT_MS ? memberIds.filter((id7) => !admitted.has(id7)) : [];
1237
+ }
1238
+ __name(mlsAdmissionWait, "mlsAdmissionWait");
1406
1239
  var MLS_DEV_ROOM_REMOVAL_DEADLINE_MS = 72 * 60 * 60 * 1e3;
1407
1240
  function parseMlsDevRoomRemoval(value) {
1408
- return boundary7(() => {
1241
+ return boundary6(() => {
1409
1242
  const input = readMlsDataRecord(value, ["version", "status", "pending", "closedAtMs"]), devices = /* @__PURE__ */ new Set(), principals = /* @__PURE__ */ new Set();
1410
- const status = ["pending", "closing", "closed"].includes(input.status) ? input.status : invalid8();
1243
+ const status = ["pending", "closing", "closed"].includes(input.status) ? input.status : invalid7();
1411
1244
  const pending = array3(input.pending, MLS_DEV_GROUP_ROSTER_MAX).map((item2) => {
1412
1245
  const entry = readMlsDataRecord(item2, ["principalId", "deviceIds", "deadlineAtMs"]);
1413
1246
  const principalId2 = parseMlsDevEnrollmentPrincipal({ type: "human", id: entry.principalId }).id;
1414
1247
  const deviceIds = array3(entry.deviceIds, MLS_DEV_GROUP_ROSTER_MAX).map(requireMlsUuid);
1415
- if (principals.has(principalId2)) invalid8();
1248
+ if (principals.has(principalId2)) invalid7();
1416
1249
  principals.add(principalId2);
1417
1250
  for (const deviceId of deviceIds) {
1418
- if (devices.has(deviceId)) invalid8();
1251
+ if (devices.has(deviceId)) invalid7();
1419
1252
  devices.add(deviceId);
1420
1253
  }
1421
1254
  return Object.freeze({ principalId: principalId2, deviceIds: Object.freeze(deviceIds), deadlineAtMs: requireMlsInteger(entry.deadlineAtMs, 1) });
1422
1255
  });
1423
1256
  const closedAtMs = input.closedAtMs === null ? null : requireMlsInteger(input.closedAtMs, 1);
1424
- if (status === "pending" ? !pending.length || closedAtMs !== null : closedAtMs === null || status === "closed" && pending.length) invalid8();
1257
+ if (status === "pending" ? !pending.length || closedAtMs !== null : closedAtMs === null || status === "closed" && pending.length) invalid7();
1425
1258
  return Object.freeze({ version: requireMlsLiteral(input.version, 1), status, pending: Object.freeze(pending), closedAtMs });
1426
1259
  });
1427
1260
  }
1428
1261
  __name(parseMlsDevRoomRemoval, "parseMlsDevRoomRemoval");
1429
1262
  function parseMlsDevGroupPreconditions(value) {
1430
- return boundary7(() => {
1263
+ return boundary6(() => {
1431
1264
  const input = readMlsDataRecord(value, ["membershipRevision", "admissionId", "targetAdmissionId"]);
1432
1265
  return Object.freeze({
1433
1266
  membershipRevision: requireMlsInteger(input.membershipRevision),
@@ -1456,33 +1289,33 @@ var unsignedFields = [
1456
1289
  ];
1457
1290
  function unsigned(input) {
1458
1291
  if (typeof input.kind !== "string" || !["create", "add", "remove"].includes(input.kind))
1459
- invalid8();
1292
+ invalid7();
1460
1293
  const kind = input.kind;
1461
1294
  const senderCredential = token(input.senderCredential), sender = parseMlsDevCredentialToken(senderCredential).unsigned.claims.device;
1462
1295
  const expectedHead = input.expectedHead === null ? null : parseMlsDevGroupHead(input.expectedHead);
1463
1296
  const epoch = requireMlsInteger(input.epoch), preconditions = parseMlsDevGroupPreconditions(input.preconditions), roster = parseMlsDevGroupRoster(input.roster);
1464
1297
  const environmentId = requireMlsEnvironmentId(input.environmentId);
1465
1298
  if (sender.environmentId !== environmentId || roster.some((entry) => entry.device.environmentId !== environmentId))
1466
- invalid8();
1299
+ invalid7();
1467
1300
  const groupInfo = input.groupInfo === null ? null : wire2(input.groupInfo), commit = input.commit === null ? null : wire2(input.commit);
1468
1301
  const welcome = input.welcome === null ? null : wire2(input.welcome);
1469
1302
  const keyPackageClaim = input.keyPackageClaim === null ? null : parseMlsDevKeyPackageClaimReceipt(input.keyPackageClaim);
1470
1303
  const removedDeviceId = input.removedDeviceId === null ? null : requireMlsUuid(input.removedDeviceId);
1471
1304
  const own = roster.find((entry) => entry.device.deviceId === sender.deviceId);
1472
1305
  if (!own || JSON.stringify(own.device) !== JSON.stringify(sender) || own.admissionId !== preconditions.admissionId)
1473
- invalid8();
1306
+ invalid7();
1474
1307
  if (kind === "create") {
1475
1308
  if (expectedHead !== null || epoch !== 0 || roster.length !== 1 || !groupInfo || commit !== null || welcome !== null || keyPackageClaim !== null || removedDeviceId !== null || preconditions.targetAdmissionId !== null)
1476
- invalid8();
1309
+ invalid7();
1477
1310
  } else {
1478
1311
  if (!expectedHead || expectedHead.sequence >= Number.MAX_SAFE_INTEGER || expectedHead.epoch >= Number.MAX_SAFE_INTEGER || epoch !== expectedHead.epoch + 1 || !commit || preconditions.targetAdmissionId === null)
1479
- invalid8();
1312
+ invalid7();
1480
1313
  if (kind === "add") {
1481
1314
  const target = roster.find((entry) => entry.device.deviceId === keyPackageClaim?.recipientDeviceId);
1482
1315
  if (!welcome || !keyPackageClaim || removedDeviceId !== null || !target || keyPackageClaim.claimantDeviceId !== sender.deviceId || keyPackageClaim.preconditions.conversationId !== input.conversationId || keyPackageClaim.preconditions.membershipRevision !== preconditions.membershipRevision || keyPackageClaim.preconditions.admissionId !== preconditions.admissionId || keyPackageClaim.preconditions.targetAdmissionId !== preconditions.targetAdmissionId || target.admissionId !== preconditions.targetAdmissionId)
1483
- invalid8();
1316
+ invalid7();
1484
1317
  } else if (!removedDeviceId || removedDeviceId === sender.deviceId || roster.some((entry) => entry.device.deviceId === removedDeviceId) || welcome !== null || keyPackageClaim !== null)
1485
- invalid8();
1318
+ invalid7();
1486
1319
  }
1487
1320
  return bounded5({
1488
1321
  version: requireMlsLiteral(input.version, 1),
@@ -1504,21 +1337,21 @@ function unsigned(input) {
1504
1337
  }
1505
1338
  __name(unsigned, "unsigned");
1506
1339
  function parseMlsDevGroupControl(value) {
1507
- return boundary7(() => {
1340
+ return boundary6(() => {
1508
1341
  const input = readMlsDataRecord(value, [...unsignedFields, "proof"]);
1509
1342
  return bounded5({ ...unsigned(input), proof: encoded4(input.proof, 64) });
1510
1343
  });
1511
1344
  }
1512
1345
  __name(parseMlsDevGroupControl, "parseMlsDevGroupControl");
1513
1346
  function parseMlsDevGroupAcceptedControl(value) {
1514
- return boundary7(() => {
1347
+ return boundary6(() => {
1515
1348
  const input = readMlsDataRecord(value, ["version", "authorization", "operationId", "control", "head", "acceptedAtMs", "membershipRevision"]);
1516
1349
  const control = parseMlsDevGroupControl(input.control), head = parseMlsDevGroupHead(input.head);
1517
1350
  if (head.sequence !== (control.expectedHead?.sequence ?? 0) + 1 || head.epoch !== control.epoch)
1518
- invalid8();
1351
+ invalid7();
1519
1352
  const membershipRevision = requireMlsInteger(input.membershipRevision);
1520
1353
  if (membershipRevision !== control.preconditions.membershipRevision && !(control.kind === "remove" && membershipRevision === control.preconditions.membershipRevision + 1))
1521
- invalid8();
1354
+ invalid7();
1522
1355
  return bounded5({
1523
1356
  version: requireMlsLiteral(input.version, 1),
1524
1357
  authorization: requireMlsLiteral(input.authorization, "group_control_only"),
@@ -1532,20 +1365,20 @@ function parseMlsDevGroupAcceptedControl(value) {
1532
1365
  }
1533
1366
  __name(parseMlsDevGroupAcceptedControl, "parseMlsDevGroupAcceptedControl");
1534
1367
  function parseMlsDevGroupAdmissionsResult(value) {
1535
- return boundary7(() => {
1368
+ return boundary6(() => {
1536
1369
  const input = readMlsDataRecord(value, ["version", "conversationId", "membershipRevision", "candidates", "waitingPrincipalIds"]);
1537
1370
  const candidates = array3(input.candidates, MLS_DEV_GROUP_ADMISSION_MAX_CANDIDATES).map((raw) => {
1538
1371
  const entry = readMlsDataRecord(raw, ["principal", "deviceId", "targetAdmissionId"]), principal2 = readMlsDataRecord(entry.principal, ["type", "id"]);
1539
- if (principal2.type !== "human" && principal2.type !== "ai_agent") invalid8();
1372
+ if (principal2.type !== "human" && principal2.type !== "ai_agent") invalid7();
1540
1373
  return Object.freeze({
1541
1374
  principal: Object.freeze({ type: principal2.type, id: id4(principal2.id) }),
1542
1375
  deviceId: requireMlsUuid(entry.deviceId),
1543
1376
  targetAdmissionId: id4(entry.targetAdmissionId)
1544
1377
  });
1545
1378
  });
1546
- if (new Set(candidates.map((entry) => entry.deviceId)).size !== candidates.length) invalid8();
1379
+ if (new Set(candidates.map((entry) => entry.deviceId)).size !== candidates.length) invalid7();
1547
1380
  const waiting = array3(input.waitingPrincipalIds, 32).map(id4);
1548
- if (new Set(waiting).size !== waiting.length) invalid8();
1381
+ if (new Set(waiting).size !== waiting.length) invalid7();
1549
1382
  return bounded5(Object.freeze({
1550
1383
  version: requireMlsLiteral(input.version, 1),
1551
1384
  conversationId: id4(input.conversationId),
@@ -1557,11 +1390,11 @@ function parseMlsDevGroupAdmissionsResult(value) {
1557
1390
  }
1558
1391
  __name(parseMlsDevGroupAdmissionsResult, "parseMlsDevGroupAdmissionsResult");
1559
1392
  function parseMlsDevGroupQuery(value) {
1560
- return boundary7(() => {
1393
+ return boundary6(() => {
1561
1394
  const input = readMlsDataRecord(value, ["version", "conversationId", "credential", "afterSequence", "limit"]);
1562
1395
  const limit2 = requireMlsInteger(input.limit, 1);
1563
1396
  if (limit2 > MLS_DEV_GROUP_QUERY_MAX_CONTROLS)
1564
- invalid8();
1397
+ invalid7();
1565
1398
  return bounded5({
1566
1399
  version: requireMlsLiteral(input.version, 1),
1567
1400
  conversationId: id4(input.conversationId),
@@ -1573,17 +1406,17 @@ function parseMlsDevGroupQuery(value) {
1573
1406
  }
1574
1407
  __name(parseMlsDevGroupQuery, "parseMlsDevGroupQuery");
1575
1408
  function parseMlsDevGroupQueryResult(value) {
1576
- return boundary7(() => {
1409
+ return boundary6(() => {
1577
1410
  const input = readMlsDataRecord(value, ["version", "conversationId", "marker", "membershipRevision", "admissionId", "roster", "controls", "nextSequence", "hasMore", "terminal"]);
1578
1411
  const conversationId = id4(input.conversationId), marker = input.marker === null ? null : parseMlsDevGroupMarker(input.marker);
1579
1412
  const controls = array3(input.controls, MLS_DEV_GROUP_QUERY_MAX_CONTROLS).map(parseMlsDevGroupAcceptedControl);
1580
1413
  const nextSequence = requireMlsInteger(input.nextSequence), terminal = boolean3(input.terminal), hasMore = boolean3(input.hasMore);
1581
1414
  for (let i = 0; i < controls.length; i++) {
1582
1415
  if (!marker || controls[i].control.conversationId !== conversationId || controls[i].control.groupId !== marker.groupId || controls[i].head.sequence > marker.head.sequence || i > 0 && controls[i].head.sequence !== controls[i - 1].head.sequence + 1)
1583
- invalid8();
1416
+ invalid7();
1584
1417
  }
1585
1418
  if (controls.length && controls.at(-1).head.sequence !== nextSequence || marker && nextSequence > marker.head.sequence || !marker && (controls.length || nextSequence || terminal || hasMore))
1586
- invalid8();
1419
+ invalid7();
1587
1420
  return bounded5({
1588
1421
  version: requireMlsLiteral(input.version, 1),
1589
1422
  conversationId,
@@ -1600,11 +1433,11 @@ function parseMlsDevGroupQueryResult(value) {
1600
1433
  }
1601
1434
  __name(parseMlsDevGroupQueryResult, "parseMlsDevGroupQueryResult");
1602
1435
  function parseMlsDevGroupContext(value) {
1603
- return boundary7(() => {
1436
+ return boundary6(() => {
1604
1437
  const input = readMlsDataRecord(value, ["version", "environmentId", "conversationId", "groupId", "deviceId", "installationId", "revision"], ["version", "environmentId", "conversationId", "groupId", "deviceId", "installationId", "revision", "protocol"]);
1605
1438
  const revision2 = requireMlsInteger(input.revision);
1606
1439
  if (revision2 >= Number.MAX_SAFE_INTEGER)
1607
- invalid8();
1440
+ invalid7();
1608
1441
  return Object.freeze({
1609
1442
  version: requireMlsLiteral(input.version, 1),
1610
1443
  environmentId: requireMlsEnvironmentId(input.environmentId),
@@ -1619,17 +1452,17 @@ function parseMlsDevGroupContext(value) {
1619
1452
  }
1620
1453
  __name(parseMlsDevGroupContext, "parseMlsDevGroupContext");
1621
1454
  function parseMlsDevGroupCommand(value) {
1622
- return boundary7(() => {
1455
+ return boundary6(() => {
1623
1456
  if (!value || typeof value !== "object")
1624
- invalid8();
1457
+ invalid7();
1625
1458
  const descriptor = Object.getOwnPropertyDescriptor(value, "op");
1626
1459
  if (!descriptor || !Object.hasOwn(descriptor, "value"))
1627
- invalid8();
1460
+ invalid7();
1628
1461
  const op = descriptor.value;
1629
1462
  if (op === "process_application") {
1630
1463
  const input2 = readMlsDataRecord(value, ["op", "entry"]), entry = parseMlsDevGroupFeedEntry(input2.entry);
1631
1464
  if (entry.kind !== "application" || !entry.receiptProof)
1632
- invalid8();
1465
+ invalid7();
1633
1466
  return bounded5({ op, entry });
1634
1467
  }
1635
1468
  if (op === "encrypt_text") {
@@ -1688,23 +1521,23 @@ function parseMlsDevGroupCommand(value) {
1688
1521
  let seal = null;
1689
1522
  if (interaction.role === "request") {
1690
1523
  if (Object.hasOwn(body, "secretKey") || input2.seal !== null)
1691
- invalid8();
1524
+ invalid7();
1692
1525
  const parsed = parseMlsDevInteractionRequestBody(interaction.kind === "secret" ? { ...body, secretKey: { kem: "x25519", publicKey: "A".repeat(43) } } : body);
1693
1526
  if (parsed.requestId !== interaction.requestId || parsed.kind !== interaction.kind || parsed.expiresAtMs !== interaction.expiresAtMs || parsed.responderIds[0] !== interaction.responderIds[0])
1694
- invalid8();
1527
+ invalid7();
1695
1528
  } else if (interaction.role === "response") {
1696
1529
  if (input2.seal === null) {
1697
1530
  const parsed = parseMlsDevInteractionResponseBody(body);
1698
1531
  if (parsed.requestId !== interaction.requestId || parsed.agentId !== interaction.agentId || "sealed" in parsed.answer)
1699
- invalid8();
1532
+ invalid7();
1700
1533
  } else {
1701
1534
  const fields3 = readMlsDataRecord(input2.seal, ["text", "publicKey", "requesterDeviceId"]), ids2 = readMlsDataRecord(body, ["requestId", "agentId"]);
1702
1535
  if (ids2.requestId !== interaction.requestId || ids2.agentId !== interaction.agentId || typeof fields3.text !== "string" || !fields3.text.trim() || [...fields3.text].length > MLS_DEV_INTERACTION_LIMITS.text || utf84.encode(fields3.text).length > MLS_DEV_SECRET_ANSWER_MAX_BYTES - 16 || new TextDecoder("utf-8", { fatal: true }).decode(utf84.encode(fields3.text)) !== fields3.text)
1703
- invalid8();
1536
+ invalid7();
1704
1537
  seal = Object.freeze({ text: fields3.text, publicKey: encoded4(fields3.publicKey, 32), requesterDeviceId: requireMlsUuid(fields3.requesterDeviceId) });
1705
1538
  }
1706
1539
  } else if (input2.seal !== null || parseMlsDevInteractionWithdrawBody(body).requestId !== interaction.requestId)
1707
- invalid8();
1540
+ invalid7();
1708
1541
  const ids = parseMlsDevTextPayload({
1709
1542
  version: 1,
1710
1543
  kind: "text",
@@ -1716,7 +1549,7 @@ function parseMlsDevGroupCommand(value) {
1716
1549
  text: "x"
1717
1550
  });
1718
1551
  if (utf84.encode(JSON.stringify(body)).length > MLS_DEV_TEXT_MAX_BYTES)
1719
- invalid8();
1552
+ invalid7();
1720
1553
  return bounded5({
1721
1554
  op,
1722
1555
  operationId: ids.operationId,
@@ -1758,7 +1591,7 @@ function parseMlsDevGroupCommand(value) {
1758
1591
  };
1759
1592
  if (op === "join") {
1760
1593
  if (common2.accepted.control.kind !== "add")
1761
- invalid8();
1594
+ invalid7();
1762
1595
  return bounded5({ op, ...common2, keyPackageId: requireMlsUuid(input2.keyPackageId) });
1763
1596
  }
1764
1597
  return bounded5({ op, ...common2 });
@@ -1768,11 +1601,11 @@ function parseMlsDevGroupCommand(value) {
1768
1601
  const fields2 = { operationId: id4(input.operationId), credential: token(input.credential), preconditions: parseMlsDevGroupPreconditions(input.preconditions) };
1769
1602
  if (op === "create") {
1770
1603
  if (fields2.preconditions.targetAdmissionId !== null)
1771
- invalid8();
1604
+ invalid7();
1772
1605
  return bounded5({ op, ...fields2 });
1773
1606
  }
1774
1607
  if (fields2.preconditions.targetAdmissionId === null)
1775
- invalid8();
1608
+ invalid7();
1776
1609
  const expectedHead = parseMlsDevGroupHead(input.expectedHead);
1777
1610
  if (op === "add")
1778
1611
  return bounded5({
@@ -1788,24 +1621,24 @@ function parseMlsDevGroupCommand(value) {
1788
1621
  expectedHead,
1789
1622
  removedDeviceId: requireMlsUuid(input.removedDeviceId)
1790
1623
  });
1791
- return invalid8();
1624
+ return invalid7();
1792
1625
  });
1793
1626
  }
1794
1627
  __name(parseMlsDevGroupCommand, "parseMlsDevGroupCommand");
1795
1628
  function parseMlsDevGroupPreparation(value) {
1796
- return boundary7(() => {
1629
+ return boundary6(() => {
1797
1630
  const input = readMlsDataRecord(value, ["wrappedState", "payload"]);
1798
1631
  if (typeof input.wrappedState !== "string" || input.wrappedState.length > MLS_DEV_GROUP_WRAPPED_MAX_BYTES || !input.wrappedState.startsWith("v1:"))
1799
- invalid8();
1632
+ invalid7();
1800
1633
  const body = input.wrappedState.slice(3);
1801
1634
  if (body.length < 40 || body.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(body))
1802
- invalid8();
1635
+ invalid7();
1803
1636
  const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1804
1637
  if (body.endsWith("==") && (alphabet.indexOf(body.at(-3)) & 15) !== 0 || !body.endsWith("==") && body.endsWith("=") && (alphabet.indexOf(body.at(-2)) & 3) !== 0)
1805
- invalid8();
1638
+ invalid7();
1806
1639
  const kind = Object.getOwnPropertyDescriptor(input.payload ?? {}, "kind");
1807
1640
  if (!kind || !Object.hasOwn(kind, "value"))
1808
- invalid8();
1641
+ invalid7();
1809
1642
  let payload;
1810
1643
  if (kind.value === "application") {
1811
1644
  const fields2 = readMlsDataRecord(input.payload, ["kind", "envelope", ...present(input.payload, ["payload"])]);
@@ -1861,7 +1694,7 @@ function parseMlsDevGroupPreparation(value) {
1861
1694
  const fields2 = readMlsDataRecord(input.payload, ["kind", "envelope", "payload"]);
1862
1695
  payload = Object.freeze({ kind: "interaction_application", envelope: parseMlsDevApplicationEnvelope(fields2.envelope), payload: plaintextJson(fields2.payload) });
1863
1696
  if (!payload.envelope.interaction)
1864
- invalid8();
1697
+ invalid7();
1865
1698
  } else if (kind.value === "interaction") {
1866
1699
  const fields2 = readMlsDataRecord(input.payload, ["kind", "messageId", "operationId", "senderDeviceId", "payload", "feedOrdinal"]);
1867
1700
  const ids = parseMlsDevTextPayload({
@@ -1905,7 +1738,7 @@ function parseMlsDevGroupPreparation(value) {
1905
1738
  const fields2 = readMlsDataRecord(input.payload, ["kind", "requestId", "text"]);
1906
1739
  const binding3 = parseMlsDevInteractionBinding({ role: "withdraw", requestId: fields2.requestId });
1907
1740
  if (typeof fields2.text !== "string" || !fields2.text.trim() || [...fields2.text].length > MLS_DEV_INTERACTION_LIMITS.text || new TextDecoder("utf-8", { fatal: true }).decode(utf84.encode(fields2.text)) !== fields2.text)
1908
- invalid8();
1741
+ invalid7();
1909
1742
  payload = Object.freeze({ kind: "secret", requestId: binding3.requestId, text: fields2.text });
1910
1743
  } else if (kind.value === "control") {
1911
1744
  const fields2 = readMlsDataRecord(input.payload, ["kind", "control"]);
@@ -1960,27 +1793,27 @@ var MlsDevApplicationValidationError = class extends Error {
1960
1793
  }
1961
1794
  };
1962
1795
  var utf85 = new TextEncoder();
1963
- function invalid9() {
1796
+ function invalid8() {
1964
1797
  throw new MlsDevApplicationValidationError();
1965
1798
  }
1966
- __name(invalid9, "invalid");
1967
- function boundary8(read) {
1799
+ __name(invalid8, "invalid");
1800
+ function boundary7(read) {
1968
1801
  try {
1969
1802
  return read();
1970
1803
  } catch {
1971
- return invalid9();
1804
+ return invalid8();
1972
1805
  }
1973
1806
  }
1974
- __name(boundary8, "boundary");
1807
+ __name(boundary7, "boundary");
1975
1808
  function bounded6(value) {
1976
1809
  if (utf85.encode(JSON.stringify(value)).length > MLS_DEV_APPLICATION_MAX_BYTES)
1977
- invalid9();
1810
+ invalid8();
1978
1811
  return Object.freeze(value);
1979
1812
  }
1980
1813
  __name(bounded6, "bounded");
1981
1814
  function id5(value) {
1982
1815
  if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..")
1983
- invalid9();
1816
+ invalid8();
1984
1817
  return value;
1985
1818
  }
1986
1819
  __name(id5, "id");
@@ -1990,31 +1823,31 @@ function isMlsDevMessageId(value) {
1990
1823
  __name(isMlsDevMessageId, "isMlsDevMessageId");
1991
1824
  function messageId(value) {
1992
1825
  if (!isMlsDevMessageId(value))
1993
- invalid9();
1826
+ invalid8();
1994
1827
  return value;
1995
1828
  }
1996
1829
  __name(messageId, "messageId");
1997
1830
  function interactionId2(value) {
1998
1831
  if (typeof value !== "string" || !MLS_DEV_INTERACTION_ID_PATTERN.test(value) || value === "." || value === "..")
1999
- invalid9();
1832
+ invalid8();
2000
1833
  return value;
2001
1834
  }
2002
1835
  __name(interactionId2, "interactionId");
2003
1836
  function parseMlsDevInteractionBinding(value) {
2004
- return boundary8(() => {
1837
+ return boundary7(() => {
2005
1838
  const role = value && typeof value === "object" ? Object.getOwnPropertyDescriptor(value, "role") : void 0;
2006
1839
  if (!role || !Object.hasOwn(role, "value"))
2007
- invalid9();
1840
+ invalid8();
2008
1841
  if (role.value === "request") {
2009
1842
  const input2 = readMlsDataRecord(value, ["role", "requestId", "kind", "responderIds", "expiresAtMs"]);
2010
1843
  if (typeof input2.kind !== "string" || !MLS_DEV_INTERACTION_KINDS.includes(input2.kind))
2011
- invalid9();
1844
+ invalid8();
2012
1845
  const responders = input2.responderIds;
2013
1846
  if (!Array.isArray(responders) || Object.getPrototypeOf(responders) !== Array.prototype || responders.length !== 1 || Reflect.ownKeys(Object.getOwnPropertyDescriptors(responders)).length !== 2)
2014
- invalid9();
1847
+ invalid8();
2015
1848
  const only = Object.getOwnPropertyDescriptor(responders, 0);
2016
1849
  if (!only || !only.enumerable || !Object.hasOwn(only, "value"))
2017
- invalid9();
1850
+ invalid8();
2018
1851
  const expiresAtMs = requireMlsInteger(input2.expiresAtMs, 1);
2019
1852
  return Object.freeze({
2020
1853
  role: "request",
@@ -2039,21 +1872,21 @@ function encoded5(value, bytes) {
2039
1872
  }
2040
1873
  __name(encoded5, "encoded");
2041
1874
  function parseMlsDevApplicationWire(value) {
2042
- return boundary8(() => {
1875
+ return boundary7(() => {
2043
1876
  if (typeof value !== "string" || value.length < 2 || value.length > Math.ceil(MLS_DEV_APPLICATION_TLS_MAX_BYTES * 4 / 3))
2044
- invalid9();
1877
+ invalid8();
2045
1878
  const bytes = Math.floor(value.length * 3 / 4);
2046
1879
  if (bytes > MLS_DEV_APPLICATION_TLS_MAX_BYTES || value.length !== Math.ceil(bytes * 4 / 3) || !/^[A-Za-z0-9_-]+$/.test(value))
2047
- invalid9();
1880
+ invalid8();
2048
1881
  const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
2049
1882
  if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0)
2050
- invalid9();
1883
+ invalid8();
2051
1884
  return value;
2052
1885
  });
2053
1886
  }
2054
1887
  __name(parseMlsDevApplicationWire, "parseMlsDevApplicationWire");
2055
1888
  function parseMlsDevApplicationPreconditions(value) {
2056
- return boundary8(() => {
1889
+ return boundary7(() => {
2057
1890
  const input = readMlsDataRecord(value, ["membershipRevision", "admissionId"]);
2058
1891
  return Object.freeze({ membershipRevision: requireMlsInteger(input.membershipRevision), admissionId: id5(input.admissionId) });
2059
1892
  });
@@ -2063,7 +1896,7 @@ var bindingFields = ["version", "environmentId", "conversationId", "groupId", "m
2063
1896
  var interactionBindingFields = [...bindingFields, "interaction"];
2064
1897
  function binding(input) {
2065
1898
  const environmentId = requireMlsEnvironmentId(input.environmentId);
2066
- if (parseMlsDevCredentialToken(input.senderCredential).unsigned.claims.device.environmentId !== environmentId) invalid9();
1899
+ if (parseMlsDevCredentialToken(input.senderCredential).unsigned.claims.device.environmentId !== environmentId) invalid8();
2067
1900
  return {
2068
1901
  version: requireMlsLiteral(input.version, 1),
2069
1902
  environmentId,
@@ -2082,14 +1915,14 @@ function fields(value, extra) {
2082
1915
  }
2083
1916
  __name(fields, "fields");
2084
1917
  function parseMlsDevApplicationEnvelope(value) {
2085
- return boundary8(() => {
1918
+ return boundary7(() => {
2086
1919
  const input = fields(value, ["ciphertext", "proof"]);
2087
1920
  return bounded6({ ...binding(input), ciphertext: parseMlsDevApplicationWire(input.ciphertext), proof: encoded5(input.proof, 64) });
2088
1921
  });
2089
1922
  }
2090
1923
  __name(parseMlsDevApplicationEnvelope, "parseMlsDevApplicationEnvelope");
2091
1924
  function parseMlsDevApplicationReceipt(value) {
2092
- return boundary8(() => {
1925
+ return boundary7(() => {
2093
1926
  const input = readMlsDataRecord(value, ["version", "authorization", "operationId", "conversationId", "groupId", "messageId", "feedOrdinal", "head", "acceptedAtMs", "envelopeHash"]);
2094
1927
  return bounded6({
2095
1928
  version: requireMlsLiteral(input.version, 1),
@@ -2108,7 +1941,7 @@ function parseMlsDevApplicationReceipt(value) {
2108
1941
  __name(parseMlsDevApplicationReceipt, "parseMlsDevApplicationReceipt");
2109
1942
  function text2(value) {
2110
1943
  if (typeof value !== "string" || !value.trim() || utf85.encode(value).length > MLS_DEV_TEXT_MAX_BYTES || new TextDecoder("utf-8", { fatal: true }).decode(utf85.encode(value)) !== value)
2111
- invalid9();
1944
+ invalid8();
2112
1945
  return value;
2113
1946
  }
2114
1947
  __name(text2, "text");
@@ -2117,13 +1950,13 @@ function textExtras2(value) {
2117
1950
  if (Object.hasOwn(value, "replyTo")) {
2118
1951
  const reply = readMlsDataRecord(value.replyTo, ["messageId", "quote"]);
2119
1952
  if ([...text2(reply.quote)].length > MLS_DEV_REPLY_QUOTE_MAX_CHARACTERS)
2120
- invalid9();
1953
+ invalid8();
2121
1954
  extras.replyTo = Object.freeze({ messageId: messageId(reply.messageId), quote: reply.quote });
2122
1955
  }
2123
1956
  if (Object.hasOwn(value, "mentions")) {
2124
1957
  const mentions = value.mentions;
2125
1958
  if (!Array.isArray(mentions) || mentions.length < 1 || mentions.length > MLS_DEV_MENTIONS_MAX || new Set(mentions).size !== mentions.length)
2126
- invalid9();
1959
+ invalid8();
2127
1960
  extras.mentions = Object.freeze(mentions.map(id5));
2128
1961
  }
2129
1962
  return extras;
@@ -2131,7 +1964,7 @@ function textExtras2(value) {
2131
1964
  __name(textExtras2, "textExtras");
2132
1965
  var optionalKeys = /* @__PURE__ */ __name((value, keys2) => value && typeof value === "object" ? keys2.filter((key) => Object.hasOwn(value, key)) : [], "optionalKeys");
2133
1966
  function parseMlsDevTextPayload(value) {
2134
- return boundary8(() => {
1967
+ return boundary7(() => {
2135
1968
  const input = readMlsDataRecord(value, ["version", "kind", "conversationId", "groupId", "messageId", "operationId", "senderDeviceId", "text", ...optionalKeys(value, ["replyTo", "mentions"])]);
2136
1969
  return bounded6({
2137
1970
  version: requireMlsLiteral(input.version, 1),
@@ -2149,19 +1982,19 @@ function parseMlsDevTextPayload(value) {
2149
1982
  __name(parseMlsDevTextPayload, "parseMlsDevTextPayload");
2150
1983
  var itemFields = ["type", "uploadId", "url", "mimeType", "sizeBytes", "fileName", "width", "height", "durationMs", "thumbnailUrl", "caption", "replyTo", "mentions"];
2151
1984
  function httpsUrl(value) {
2152
- if (typeof value !== "string" || value.length > 2048) invalid9();
2153
- const url = boundary8(() => new URL(value));
2154
- if (url.protocol !== "https:" || url.username || url.password) invalid9();
1985
+ if (typeof value !== "string" || value.length > 2048) invalid8();
1986
+ const url = boundary7(() => new URL(value));
1987
+ if (url.protocol !== "https:" || url.username || url.password) invalid8();
2155
1988
  return value;
2156
1989
  }
2157
1990
  __name(httpsUrl, "httpsUrl");
2158
- var dimension = /* @__PURE__ */ __name((value) => requireMlsInteger(value, 0) <= 1e5 ? value : invalid9(), "dimension");
1991
+ var dimension = /* @__PURE__ */ __name((value) => requireMlsInteger(value, 0) <= 1e5 ? value : invalid8(), "dimension");
2159
1992
  function item(value) {
2160
1993
  const input = readMlsDataRecord(value, ["type", "uploadId", "url", "mimeType", "sizeBytes", ...optionalKeys(value, itemFields.slice(5))]);
2161
1994
  if (!MLS_DEV_ITEM_TYPES.some((type) => type === input.type) || typeof input.mimeType !== "string" || !/^[a-z0-9.+-]{1,64}\/[a-z0-9.+-]{1,128}$/i.test(input.mimeType))
2162
- invalid9();
1995
+ invalid8();
2163
1996
  if (input.fileName !== void 0 && (typeof input.fileName !== "string" || !input.fileName.trim() || [...input.fileName].length > 240))
2164
- invalid9();
1997
+ invalid8();
2165
1998
  return Object.freeze({
2166
1999
  type: input.type,
2167
2000
  uploadId: requireMlsUuid(input.uploadId),
@@ -2177,7 +2010,7 @@ function item(value) {
2177
2010
  }
2178
2011
  __name(item, "item");
2179
2012
  function parseMlsDevItemPayload(value) {
2180
- return boundary8(() => {
2013
+ return boundary7(() => {
2181
2014
  const input = readMlsDataRecord(value, ["version", "kind", "conversationId", "groupId", "messageId", "operationId", "senderDeviceId", "item"]);
2182
2015
  const payload = {
2183
2016
  version: requireMlsLiteral(input.version, 1),
@@ -2190,7 +2023,7 @@ function parseMlsDevItemPayload(value) {
2190
2023
  item: item(input.item)
2191
2024
  };
2192
2025
  if (utf85.encode(JSON.stringify(payload)).length > MLS_DEV_TEXT_MAX_BYTES)
2193
- invalid9();
2026
+ invalid8();
2194
2027
  return bounded6(payload);
2195
2028
  });
2196
2029
  }
@@ -2212,40 +2045,443 @@ function framed(domain4, value, operationId) {
2212
2045
  }
2213
2046
  __name(framed, "framed");
2214
2047
  function encodeMlsDevApplicationEnvelopeHash(value, operationId) {
2215
- return boundary8(() => framed("canon.mls.dev-application-envelope.v1\0", parseMlsDevApplicationEnvelope(value), operationId));
2048
+ return boundary7(() => framed("canon.mls.dev-application-envelope.v1\0", parseMlsDevApplicationEnvelope(value), operationId));
2216
2049
  }
2217
2050
  __name(encodeMlsDevApplicationEnvelopeHash, "encodeMlsDevApplicationEnvelopeHash");
2218
2051
 
2219
- // ../backend-contracts/src/messageText.ts
2220
- var HUMAN_MESSAGE_TEXT_MAX_BYTES = 32 * 1024;
2221
- var UTF8_ENCODER = new TextEncoder();
2222
-
2223
- // ../backend-contracts/src/runtimeCardFields.ts
2224
- var RUNTIME_CARD_FIELD_TYPES = [
2225
- "text",
2226
- "textarea",
2227
- "select",
2228
- "multiSelect",
2229
- "boolean",
2230
- "date",
2231
- "number",
2232
- "currency",
2233
- "searchSelect",
2234
- "lineItems"
2235
- ];
2236
- var RUNTIME_CARD_LINE_ITEM_COLUMN_TYPES = [
2237
- "text",
2238
- "number",
2239
- "currency",
2240
- "date",
2241
- "select"
2242
- ];
2243
-
2244
- // ../backend-contracts/src/membershipChange.ts
2245
- function isRecord(value) {
2246
- return typeof value === "object" && value !== null && !Array.isArray(value);
2052
+ // ../backend-contracts/src/mlsDevFeedReceipt.ts
2053
+ var MlsDevFeedReceiptValidationError = class extends Error {
2054
+ static {
2055
+ __name(this, "MlsDevFeedReceiptValidationError");
2056
+ }
2057
+ code = "INVALID_MLS_DEV_FEED_RECEIPT";
2058
+ constructor() {
2059
+ super("INVALID_MLS_DEV_FEED_RECEIPT");
2060
+ this.name = "MlsDevFeedReceiptValidationError";
2061
+ }
2062
+ };
2063
+ function invalid9() {
2064
+ throw new MlsDevFeedReceiptValidationError();
2065
+ }
2066
+ __name(invalid9, "invalid");
2067
+ function boundary8(read) {
2068
+ try {
2069
+ return read();
2070
+ } catch {
2071
+ return invalid9();
2072
+ }
2073
+ }
2074
+ __name(boundary8, "boundary");
2075
+ function parseMlsDevReceiptKeyVersion(value, environmentId) {
2076
+ return boundary8(() => {
2077
+ if (typeof value !== "string" || value.length > 200) invalid9();
2078
+ const owner = mlsEnvironmentOfReceiptKeyVersion(value);
2079
+ if (!owner || environmentId !== void 0 && owner !== environmentId) invalid9();
2080
+ return value;
2081
+ });
2082
+ }
2083
+ __name(parseMlsDevReceiptKeyVersion, "parseMlsDevReceiptKeyVersion");
2084
+ function parseMlsDevFeedReceiptProof(value) {
2085
+ return boundary8(() => {
2086
+ const input = readMlsDataRecord(value, ["keyVersion", "signature"]);
2087
+ decodeCanonicalMlsBase64Url(input.signature, 64);
2088
+ return Object.freeze({ keyVersion: parseMlsDevReceiptKeyVersion(input.keyVersion), signature: input.signature });
2089
+ });
2090
+ }
2091
+ __name(parseMlsDevFeedReceiptProof, "parseMlsDevFeedReceiptProof");
2092
+ var MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW = "MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW";
2093
+ function isMlsDevReceiptClockSkew(value) {
2094
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
2095
+ const keys2 = Object.keys(value).sort().join(), input = value;
2096
+ return (keys2 === "error,ok,retryable" || keys2 === "error,ok,retryable,version" && input.version === 1) && input.ok === false && input.error === MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW && input.retryable === true;
2097
+ }
2098
+ __name(isMlsDevReceiptClockSkew, "isMlsDevReceiptClockSkew");
2099
+
2100
+ // ../backend-contracts/src/mlsDevCredentialReconciliation.ts
2101
+ var MLS_DEV_CREDENTIAL_RECONCILIATION_CHALLENGE_TTL_MS = 3e5;
2102
+ var MLS_DEV_CREDENTIAL_RECONCILIATION_MAX_BYTES = 8192;
2103
+ var MlsDevCredentialReconciliationValidationError = class extends Error {
2104
+ static {
2105
+ __name(this, "MlsDevCredentialReconciliationValidationError");
2106
+ }
2107
+ code = "INVALID_MLS_DEV_CREDENTIAL_RECONCILIATION";
2108
+ constructor() {
2109
+ super("INVALID_MLS_DEV_CREDENTIAL_RECONCILIATION");
2110
+ this.name = "MlsDevCredentialReconciliationValidationError";
2111
+ }
2112
+ };
2113
+ var utf86 = new TextEncoder();
2114
+ var domain2 = utf86.encode("canon.mls.credential-reconciliation-proof.v1\0");
2115
+ function invalid10() {
2116
+ throw new MlsDevCredentialReconciliationValidationError();
2117
+ }
2118
+ __name(invalid10, "invalid");
2119
+ function boundary9(read) {
2120
+ try {
2121
+ return read();
2122
+ } catch {
2123
+ return invalid10();
2124
+ }
2125
+ }
2126
+ __name(boundary9, "boundary");
2127
+ function bounded7(value) {
2128
+ if (utf86.encode(JSON.stringify(value)).length > MLS_DEV_CREDENTIAL_RECONCILIATION_MAX_BYTES) invalid10();
2129
+ return Object.freeze(value);
2130
+ }
2131
+ __name(bounded7, "bounded");
2132
+ function encoded6(value, bytes) {
2133
+ decodeCanonicalMlsBase64Url(value, bytes);
2134
+ return value;
2135
+ }
2136
+ __name(encoded6, "encoded");
2137
+ function parseMlsDevCredentialReconciliationBegin(value) {
2138
+ return boundary9(() => {
2139
+ const input = readMlsDataRecord(value, ["version", "deviceId", "requestId", "expectedCredentialGeneration"]);
2140
+ return bounded7({
2141
+ version: requireMlsLiteral(input.version, 1),
2142
+ deviceId: requireMlsUuid(input.deviceId),
2143
+ requestId: requireMlsUuid(input.requestId),
2144
+ expectedCredentialGeneration: requireMlsInteger(input.expectedCredentialGeneration)
2145
+ });
2146
+ });
2147
+ }
2148
+ __name(parseMlsDevCredentialReconciliationBegin, "parseMlsDevCredentialReconciliationBegin");
2149
+ function parseMlsDevCredentialReconciliationChallenge(value) {
2150
+ return boundary9(() => {
2151
+ const input = readMlsDataRecord(value, [
2152
+ "version",
2153
+ "challengeId",
2154
+ "requestId",
2155
+ "nonce",
2156
+ "device",
2157
+ "expectedCredentialGeneration",
2158
+ "issuedAtMs",
2159
+ "expiresAtMs"
2160
+ ]);
2161
+ const device = parseMlsDevEnrollmentResult({ version: 1, authorization: "registration_only", device: input.device }).device;
2162
+ const issuedAtMs = requireMlsInteger(input.issuedAtMs), expiresAtMs = requireMlsInteger(input.expiresAtMs);
2163
+ if (issuedAtMs < device.registeredAtMs || expiresAtMs - issuedAtMs !== MLS_DEV_CREDENTIAL_RECONCILIATION_CHALLENGE_TTL_MS) invalid10();
2164
+ return bounded7({
2165
+ version: requireMlsLiteral(input.version, 1),
2166
+ challengeId: requireMlsUuid(input.challengeId),
2167
+ requestId: requireMlsUuid(input.requestId),
2168
+ nonce: encoded6(input.nonce, 32),
2169
+ device,
2170
+ expectedCredentialGeneration: requireMlsInteger(input.expectedCredentialGeneration),
2171
+ issuedAtMs,
2172
+ expiresAtMs
2173
+ });
2174
+ });
2175
+ }
2176
+ __name(parseMlsDevCredentialReconciliationChallenge, "parseMlsDevCredentialReconciliationChallenge");
2177
+ function parseMlsDevCredentialReconciliationComplete(value) {
2178
+ return boundary9(() => {
2179
+ const input = readMlsDataRecord(value, ["version", "challengeId", "proof"]);
2180
+ return bounded7({ version: requireMlsLiteral(input.version, 1), challengeId: requireMlsUuid(input.challengeId), proof: encoded6(input.proof, 64) });
2181
+ });
2182
+ }
2183
+ __name(parseMlsDevCredentialReconciliationComplete, "parseMlsDevCredentialReconciliationComplete");
2184
+ function parseMlsDevCredentialReconciliationReceipt(value) {
2185
+ return boundary9(() => {
2186
+ const input = readMlsDataRecord(value, ["version", "authorization", "challenge", "observedCredentialGeneration", "observedAtMs"]);
2187
+ const challenge = parseMlsDevCredentialReconciliationChallenge(input.challenge);
2188
+ const observedCredentialGeneration = requireMlsInteger(input.observedCredentialGeneration), observedAtMs = requireMlsInteger(input.observedAtMs);
2189
+ if (observedCredentialGeneration < challenge.expectedCredentialGeneration || observedAtMs < challenge.issuedAtMs || observedAtMs >= challenge.expiresAtMs) invalid10();
2190
+ return bounded7({
2191
+ version: requireMlsLiteral(input.version, 1),
2192
+ authorization: requireMlsLiteral(input.authorization, "credential_generation_observation_only"),
2193
+ challenge,
2194
+ observedCredentialGeneration,
2195
+ observedAtMs
2196
+ });
2197
+ });
2198
+ }
2199
+ __name(parseMlsDevCredentialReconciliationReceipt, "parseMlsDevCredentialReconciliationReceipt");
2200
+
2201
+ // ../backend-contracts/src/mlsDevDeviceCustody.ts
2202
+ var MLS_DEV_DEVICE_CONTEXT_MAX_BYTES = 2048;
2203
+ var MLS_DEV_DEVICE_COMMAND_MAX_BYTES = 16384;
2204
+ var MLS_DEV_DEVICE_WRAPPED_STATE_MAX_BYTES = 6144;
2205
+ var MlsDevDeviceCustodyValidationError = class extends Error {
2206
+ static {
2207
+ __name(this, "MlsDevDeviceCustodyValidationError");
2208
+ }
2209
+ code = "INVALID_MLS_DEV_DEVICE_CUSTODY";
2210
+ constructor() {
2211
+ super("INVALID_MLS_DEV_DEVICE_CUSTODY");
2212
+ this.name = "MlsDevDeviceCustodyValidationError";
2213
+ }
2214
+ };
2215
+ var utf87 = new TextEncoder();
2216
+ function invalid11() {
2217
+ throw new MlsDevDeviceCustodyValidationError();
2218
+ }
2219
+ __name(invalid11, "invalid");
2220
+ function boundary10(read) {
2221
+ try {
2222
+ return read();
2223
+ } catch {
2224
+ return invalid11();
2225
+ }
2226
+ }
2227
+ __name(boundary10, "boundary");
2228
+ function bounded8(value, limit2) {
2229
+ if (utf87.encode(JSON.stringify(value)).length > limit2) invalid11();
2230
+ return Object.freeze(value);
2231
+ }
2232
+ __name(bounded8, "bounded");
2233
+ function binding2(input) {
2234
+ return {
2235
+ version: requireMlsLiteral(input.version, 1),
2236
+ environmentId: requireMlsEnvironmentId(input.environmentId),
2237
+ principal: parseMlsDevEnrollmentPrincipal(input.principal),
2238
+ installationId: parseMlsDevInstallationId(input.installationId)
2239
+ };
2240
+ }
2241
+ __name(binding2, "binding");
2242
+ function parseMlsDevDeviceBinding(value) {
2243
+ return boundary10(() => bounded8(binding2(readMlsDataRecord(value, ["version", "environmentId", "principal", "installationId"])), MLS_DEV_DEVICE_CONTEXT_MAX_BYTES));
2244
+ }
2245
+ __name(parseMlsDevDeviceBinding, "parseMlsDevDeviceBinding");
2246
+ function parseMlsDevDeviceContext(value) {
2247
+ return boundary10(() => {
2248
+ const input = readMlsDataRecord(value, ["version", "environmentId", "principal", "installationId", "revision"]);
2249
+ const revision2 = requireMlsInteger(input.revision);
2250
+ if (revision2 >= Number.MAX_SAFE_INTEGER) invalid11();
2251
+ return bounded8({ ...binding2(input), revision: revision2 }, MLS_DEV_DEVICE_CONTEXT_MAX_BYTES);
2252
+ });
2253
+ }
2254
+ __name(parseMlsDevDeviceContext, "parseMlsDevDeviceContext");
2255
+ function parseMlsDevDeviceCommand(value) {
2256
+ return boundary10(() => {
2257
+ if (value === null || typeof value !== "object") invalid11();
2258
+ const descriptor = Object.getOwnPropertyDescriptor(value, "op");
2259
+ if (!descriptor || !Object.hasOwn(descriptor, "value")) invalid11();
2260
+ if (descriptor.value === "create") {
2261
+ const input2 = readMlsDataRecord(value, ["op"]);
2262
+ return Object.freeze({ op: requireMlsLiteral(input2.op, "create") });
2263
+ }
2264
+ if (descriptor.value === "enrollment_proof") {
2265
+ const input2 = readMlsDataRecord(value, ["op", "challenge"]);
2266
+ return bounded8({
2267
+ op: requireMlsLiteral(input2.op, "enrollment_proof"),
2268
+ challenge: parseMlsDevEnrollmentChallenge(input2.challenge)
2269
+ }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
2270
+ }
2271
+ if (descriptor.value === "credential_reconciliation_proof") {
2272
+ const input2 = readMlsDataRecord(value, ["op", "challenge", "expectedCredentialGeneration"]);
2273
+ const challenge2 = parseMlsDevCredentialReconciliationChallenge(input2.challenge);
2274
+ const expectedCredentialGeneration2 = requireMlsInteger(input2.expectedCredentialGeneration);
2275
+ if (challenge2.expectedCredentialGeneration !== expectedCredentialGeneration2) invalid11();
2276
+ return bounded8({
2277
+ op: requireMlsLiteral(input2.op, "credential_reconciliation_proof"),
2278
+ challenge: challenge2,
2279
+ expectedCredentialGeneration: expectedCredentialGeneration2
2280
+ }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
2281
+ }
2282
+ if (descriptor.value !== "credential_proof") invalid11();
2283
+ const input = readMlsDataRecord(value, ["op", "challenge", "registrationResult", "expectedCredentialGeneration"]);
2284
+ const challenge = parseMlsDevCredentialChallenge(input.challenge);
2285
+ const registrationResult = parseMlsDevEnrollmentResult(input.registrationResult);
2286
+ const expectedCredentialGeneration = requireMlsInteger(input.expectedCredentialGeneration);
2287
+ if (expectedCredentialGeneration >= Number.MAX_SAFE_INTEGER || challenge.credential.claims.generation !== expectedCredentialGeneration + 1 || JSON.stringify(challenge.credential.claims.device) !== JSON.stringify(registrationResult.device)) invalid11();
2288
+ return bounded8({
2289
+ op: requireMlsLiteral(input.op, "credential_proof"),
2290
+ challenge,
2291
+ registrationResult,
2292
+ expectedCredentialGeneration
2293
+ }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
2294
+ });
2295
+ }
2296
+ __name(parseMlsDevDeviceCommand, "parseMlsDevDeviceCommand");
2297
+ function encoded7(value, bytes) {
2298
+ decodeCanonicalMlsBase64Url(value, bytes);
2299
+ return value;
2300
+ }
2301
+ __name(encoded7, "encoded");
2302
+ function wrapped(value) {
2303
+ if (typeof value !== "string" || value.length > MLS_DEV_DEVICE_WRAPPED_STATE_MAX_BYTES || !value.startsWith("v1:")) invalid11();
2304
+ const body = value.slice(3);
2305
+ if (body.length < 40 || body.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(body)) invalid11();
2306
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2307
+ if (body.endsWith("==") && (alphabet.indexOf(body.at(-3)) & 15) !== 0) invalid11();
2308
+ if (!body.endsWith("==") && body.endsWith("=") && (alphabet.indexOf(body.at(-2)) & 3) !== 0) invalid11();
2309
+ return value;
2310
+ }
2311
+ __name(wrapped, "wrapped");
2312
+ function parseMlsDevDevicePreparation(value, op) {
2313
+ return boundary10(() => {
2314
+ if (!["create", "enrollment_proof", "credential_proof", "credential_reconciliation_proof"].includes(op)) invalid11();
2315
+ const input = readMlsDataRecord(value, ["wrappedState", "payload"]);
2316
+ const payload = readMlsDataRecord(input.payload, op === "create" ? ["signaturePublicKey"] : ["signaturePublicKey", "proof"]);
2317
+ return bounded8({ wrappedState: wrapped(input.wrappedState), payload: Object.freeze({
2318
+ signaturePublicKey: encoded7(payload.signaturePublicKey, 32),
2319
+ ...op === "create" ? {} : { proof: encoded7(payload.proof, 64) }
2320
+ }) }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
2321
+ });
2322
+ }
2323
+ __name(parseMlsDevDevicePreparation, "parseMlsDevDevicePreparation");
2324
+
2325
+ // ../backend-contracts/src/upload-mime-types.ts
2326
+ var MIME_TYPE_RE = /^[a-z0-9.+-]+\/[a-z0-9.+-]+$/i;
2327
+ var SAFE_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set([
2328
+ "image/jpeg",
2329
+ "image/png",
2330
+ "image/webp",
2331
+ "image/gif"
2332
+ ]);
2333
+ var SAFE_AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
2334
+ "audio/mp4",
2335
+ "audio/x-m4a",
2336
+ "audio/mpeg",
2337
+ "audio/webm",
2338
+ "audio/ogg",
2339
+ "audio/wav",
2340
+ // ADTS AAC — the future Android streamable-memo lane; harmless standalone.
2341
+ "audio/aac"
2342
+ ]);
2343
+ var SAFE_VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
2344
+ "video/mp4",
2345
+ "video/quicktime",
2346
+ "video/webm",
2347
+ "video/x-m4v"
2348
+ ]);
2349
+ var SAFE_FILE_MIME_TYPES = /* @__PURE__ */ new Set([
2350
+ "application/pdf",
2351
+ "text/plain",
2352
+ "text/markdown",
2353
+ "text/x-markdown",
2354
+ "text/csv",
2355
+ "application/csv",
2356
+ "application/json",
2357
+ "application/zip",
2358
+ "application/vnd.ms-excel",
2359
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
2360
+ ]);
2361
+ var SAFE_FILE_MIME_BY_EXTENSION = {
2362
+ csv: "text/csv",
2363
+ json: "application/json",
2364
+ md: "text/markdown",
2365
+ markdown: "text/markdown",
2366
+ pdf: "application/pdf",
2367
+ txt: "text/plain",
2368
+ xls: "application/vnd.ms-excel",
2369
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
2370
+ zip: "application/zip"
2371
+ };
2372
+ var SAFE_VIDEO_MIME_BY_EXTENSION = {
2373
+ m4v: "video/x-m4v",
2374
+ mov: "video/quicktime",
2375
+ mp4: "video/mp4",
2376
+ webm: "video/webm"
2377
+ };
2378
+ var SAFE_AUDIO_MIME_BY_EXTENSION = {
2379
+ aac: "audio/aac",
2380
+ m4a: "audio/x-m4a",
2381
+ mp3: "audio/mpeg",
2382
+ oga: "audio/ogg",
2383
+ ogg: "audio/ogg",
2384
+ wav: "audio/wav"
2385
+ };
2386
+ function normalizeMimeType(value) {
2387
+ if (typeof value !== "string") return null;
2388
+ const normalized = value.split(";")[0].trim().toLowerCase();
2389
+ if (!MIME_TYPE_RE.test(normalized)) return null;
2390
+ if (normalized === "image/jpg") return "image/jpeg";
2391
+ return normalized;
2392
+ }
2393
+ __name(normalizeMimeType, "normalizeMimeType");
2394
+ function inferSafeFileMimeTypeFromName(value) {
2395
+ if (typeof value !== "string") return null;
2396
+ const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
2397
+ return SAFE_FILE_MIME_BY_EXTENSION[extension] ?? null;
2398
+ }
2399
+ __name(inferSafeFileMimeTypeFromName, "inferSafeFileMimeTypeFromName");
2400
+ function inferSafeVideoMimeTypeFromName(value) {
2401
+ if (typeof value !== "string") return null;
2402
+ const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
2403
+ return SAFE_VIDEO_MIME_BY_EXTENSION[extension] ?? null;
2404
+ }
2405
+ __name(inferSafeVideoMimeTypeFromName, "inferSafeVideoMimeTypeFromName");
2406
+ function inferSafeAudioMimeTypeFromName(value) {
2407
+ if (typeof value !== "string") return null;
2408
+ const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
2409
+ return SAFE_AUDIO_MIME_BY_EXTENSION[extension] ?? null;
2410
+ }
2411
+ __name(inferSafeAudioMimeTypeFromName, "inferSafeAudioMimeTypeFromName");
2412
+ function shouldTrustSafeFileName(mimeType) {
2413
+ return !mimeType || mimeType === "application/octet-stream" || mimeType === "application/vnd.ms-excel" || mimeType === "text/plain";
2414
+ }
2415
+ __name(shouldTrustSafeFileName, "shouldTrustSafeFileName");
2416
+ function classifyAllowedUploadMimeType(value) {
2417
+ const mimeType = normalizeMimeType(value);
2418
+ if (!mimeType) return null;
2419
+ if (SAFE_IMAGE_MIME_TYPES.has(mimeType)) return "image";
2420
+ if (SAFE_AUDIO_MIME_TYPES.has(mimeType)) return "audio";
2421
+ if (SAFE_VIDEO_MIME_TYPES.has(mimeType)) return "video";
2422
+ if (SAFE_FILE_MIME_TYPES.has(mimeType)) return "file";
2423
+ return null;
2424
+ }
2425
+ __name(classifyAllowedUploadMimeType, "classifyAllowedUploadMimeType");
2426
+ function resolveAllowedUploadMimeType(input) {
2427
+ const normalizedMimeType = normalizeMimeType(input.mimeType);
2428
+ const hasExplicitMimeType = typeof input.mimeType === "string" && input.mimeType.trim().length > 0;
2429
+ const inferredVideoMimeType = inferSafeVideoMimeTypeFromName(input.fileName);
2430
+ const inferredAudioMimeType = inferSafeAudioMimeTypeFromName(input.fileName);
2431
+ const inferredFileMimeType = inferSafeFileMimeTypeFromName(input.fileName);
2432
+ if (hasExplicitMimeType && !normalizedMimeType) {
2433
+ return null;
2434
+ }
2435
+ if (inferredVideoMimeType && (!normalizedMimeType || normalizedMimeType === "application/octet-stream")) {
2436
+ return inferredVideoMimeType;
2437
+ }
2438
+ if (inferredAudioMimeType && (!normalizedMimeType || normalizedMimeType === "application/octet-stream")) {
2439
+ return inferredAudioMimeType;
2440
+ }
2441
+ if (inferredFileMimeType && shouldTrustSafeFileName(normalizedMimeType)) {
2442
+ return inferredFileMimeType;
2443
+ }
2444
+ if (normalizedMimeType && classifyAllowedUploadMimeType(normalizedMimeType)) {
2445
+ return normalizedMimeType;
2446
+ }
2447
+ return normalizedMimeType ? null : inferredFileMimeType;
2448
+ }
2449
+ __name(resolveAllowedUploadMimeType, "resolveAllowedUploadMimeType");
2450
+
2451
+ // ../backend-contracts/src/messageText.ts
2452
+ var HUMAN_MESSAGE_TEXT_MAX_BYTES = 32 * 1024;
2453
+ var UTF8_ENCODER = new TextEncoder();
2454
+
2455
+ // ../backend-contracts/src/runtimeCardFields.ts
2456
+ var RUNTIME_CARD_FIELD_TYPES = [
2457
+ "text",
2458
+ "textarea",
2459
+ "select",
2460
+ "multiSelect",
2461
+ "boolean",
2462
+ "date",
2463
+ "number",
2464
+ "currency",
2465
+ "searchSelect",
2466
+ "lineItems"
2467
+ ];
2468
+ var RUNTIME_CARD_LINE_ITEM_COLUMN_TYPES = [
2469
+ "text",
2470
+ "number",
2471
+ "currency",
2472
+ "date",
2473
+ "select"
2474
+ ];
2475
+
2476
+ // ../backend-contracts/src/membershipChange.ts
2477
+ function isRecord(value) {
2478
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2247
2479
  }
2248
2480
  __name(isRecord, "isRecord");
2481
+ function isMembershipChangeMessage(message) {
2482
+ return isRecord(message.metadata) && message.metadata.type === "membership_change";
2483
+ }
2484
+ __name(isMembershipChangeMessage, "isMembershipChangeMessage");
2249
2485
  function isNameOrId(value) {
2250
2486
  return value === null || typeof value === "string" && value.trim().length > 0;
2251
2487
  }
@@ -2273,15 +2509,262 @@ function formatMembershipChangeNotice(metadata, currentUserId) {
2273
2509
  if (metadata.action === "left") {
2274
2510
  return `${isMember ? "You" : metadata.memberName} left`;
2275
2511
  }
2276
- const actor = isActor ? "You" : metadata.actorName ?? "A member";
2277
- const member2 = isMember ? "you" : metadata.memberName;
2278
- return `${actor} ${metadata.action} ${member2}`;
2512
+ const actor = isActor ? "You" : metadata.actorName ?? "A member";
2513
+ const member2 = isMember ? "you" : metadata.memberName;
2514
+ return `${actor} ${metadata.action} ${member2}`;
2515
+ }
2516
+ __name(formatMembershipChangeNotice, "formatMembershipChangeNotice");
2517
+
2518
+ // ../backend-contracts/src/turnProtocol.ts
2519
+ var ACTIVE_TURN_STALE_THRESHOLD_MS = 30 * 60 * 1e3;
2520
+ var WAITING_INPUT_STALE_THRESHOLD_MS = 12 * 60 * 60 * 1e3;
2521
+ var TURN_SEMANTICS = [
2522
+ "progress",
2523
+ "turn_complete",
2524
+ "control"
2525
+ ];
2526
+ var DELIVERY_INTENTS = [
2527
+ "queue",
2528
+ "interrupt",
2529
+ "interleave",
2530
+ "stop"
2531
+ ];
2532
+ function isRecord2(value) {
2533
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2534
+ }
2535
+ __name(isRecord2, "isRecord");
2536
+ function normalizeTurnMetadata(metadata) {
2537
+ if (!isRecord2(metadata)) return null;
2538
+ const turnId = typeof metadata.turnId === "string" && metadata.turnId.trim() ? metadata.turnId.trim() : null;
2539
+ const turnSemantics = TURN_SEMANTICS.includes(metadata.turnSemantics) ? metadata.turnSemantics : void 0;
2540
+ const deliveryIntent = DELIVERY_INTENTS.includes(metadata.deliveryIntent) ? metadata.deliveryIntent : void 0;
2541
+ const replyBehavior = metadata.replyBehavior === "allow_auto_reply" || metadata.replyBehavior === "suppress_auto_reply" ? metadata.replyBehavior : void 0;
2542
+ const inboundDisposition = metadata.inboundDisposition === "queued" || metadata.inboundDisposition === "accepted_now" || metadata.inboundDisposition === "interleaved" || metadata.inboundDisposition === "trigger_suppressed" || metadata.inboundDisposition === "rejected" || metadata.inboundDisposition === "cancelled" ? metadata.inboundDisposition : void 0;
2543
+ const requestedTurnMode = typeof metadata.requestedTurnMode === "string" && /^[A-Za-z0-9_.:-]{1,80}$/.test(metadata.requestedTurnMode.trim()) ? metadata.requestedTurnMode.trim() : void 0;
2544
+ if (!turnId && !turnSemantics && !deliveryIntent && !replyBehavior && !inboundDisposition && !requestedTurnMode) {
2545
+ return null;
2546
+ }
2547
+ return {
2548
+ ...turnId ? { turnId } : {},
2549
+ ...turnSemantics ? { turnSemantics } : {},
2550
+ ...deliveryIntent ? { deliveryIntent } : {},
2551
+ ...replyBehavior ? { replyBehavior } : {},
2552
+ ...inboundDisposition ? { inboundDisposition } : {},
2553
+ ...requestedTurnMode ? { requestedTurnMode } : {}
2554
+ };
2555
+ }
2556
+ __name(normalizeTurnMetadata, "normalizeTurnMetadata");
2557
+ function resolveTurnMessageSemantics(input) {
2558
+ if (isMembershipChangeMessage(input)) return "control";
2559
+ const turnMetadata = normalizeTurnMetadata(input.metadata);
2560
+ if (turnMetadata?.turnSemantics) return turnMetadata.turnSemantics;
2561
+ if (input.senderType === "human") return "turn_complete";
2562
+ return "progress";
2563
+ }
2564
+ __name(resolveTurnMessageSemantics, "resolveTurnMessageSemantics");
2565
+ function shouldTriggerAgentTurn(input) {
2566
+ if (isMembershipChangeMessage(input)) {
2567
+ return { allow: false, semantics: "control", reason: "membership notices do not trigger agent replies" };
2568
+ }
2569
+ const semantics = resolveTurnMessageSemantics(input);
2570
+ const turnMetadata = normalizeTurnMetadata(input.metadata);
2571
+ if (turnMetadata?.replyBehavior === "suppress_auto_reply") {
2572
+ return {
2573
+ allow: false,
2574
+ semantics,
2575
+ reason: "metadata explicitly suppresses auto-reply"
2576
+ };
2577
+ }
2578
+ if (input.senderType === "human") {
2579
+ return {
2580
+ allow: true,
2581
+ semantics,
2582
+ reason: "human messages always remain triggerable"
2583
+ };
2584
+ }
2585
+ if (semantics === "progress") {
2586
+ return {
2587
+ allow: false,
2588
+ semantics,
2589
+ reason: turnMetadata?.turnSemantics === "progress" ? "non-final agent progress does not trigger other agents" : "agent messages require explicit turn_complete semantics"
2590
+ };
2591
+ }
2592
+ return {
2593
+ allow: true,
2594
+ semantics,
2595
+ reason: "agent message is treated as turn-complete"
2596
+ };
2597
+ }
2598
+ __name(shouldTriggerAgentTurn, "shouldTriggerAgentTurn");
2599
+
2600
+ // ../backend-contracts/src/agentBehaviorPolicy.ts
2601
+ var PARTICIPATION_HISTORY_FETCH_LIMIT = 50;
2602
+ var DEFAULT_GROUP_MAX_CONSECUTIVE_AGENT_TURNS = 4;
2603
+ var DEFAULT_DIRECT_MAX_CONSECUTIVE_AGENT_TURNS = 4;
2604
+ function defaultMaxConsecutiveAgentTurns(conversationType) {
2605
+ if (conversationType === "group") {
2606
+ return DEFAULT_GROUP_MAX_CONSECUTIVE_AGENT_TURNS;
2607
+ }
2608
+ if (conversationType === "direct") {
2609
+ return DEFAULT_DIRECT_MAX_CONSECUTIVE_AGENT_TURNS;
2610
+ }
2611
+ return null;
2612
+ }
2613
+ __name(defaultMaxConsecutiveAgentTurns, "defaultMaxConsecutiveAgentTurns");
2614
+ var DEFAULT_POLICY = {
2615
+ participation: {
2616
+ style: "natural",
2617
+ allowAgentToAgent: true,
2618
+ allowHumanToAgent: true,
2619
+ allowLongRunningCollaboration: true,
2620
+ requireMentionForGroupReplies: false,
2621
+ maxConsecutiveAgentTurns: null
2622
+ },
2623
+ instructions: [],
2624
+ source: {
2625
+ hasAgentDefault: false,
2626
+ hasConversationOverride: false
2627
+ }
2628
+ };
2629
+ function coalesceBoolean(overrideValue, fallbackValue, defaultValue) {
2630
+ if (typeof overrideValue === "boolean") return overrideValue;
2631
+ if (typeof fallbackValue === "boolean") return fallbackValue;
2632
+ return defaultValue;
2633
+ }
2634
+ __name(coalesceBoolean, "coalesceBoolean");
2635
+ function normalizeAgentBehaviorInstructions(value) {
2636
+ if (typeof value !== "string") return null;
2637
+ const trimmed = value.trim();
2638
+ return trimmed.length > 0 ? trimmed : null;
2639
+ }
2640
+ __name(normalizeAgentBehaviorInstructions, "normalizeAgentBehaviorInstructions");
2641
+ function resolveAgentBehaviorPolicy(params) {
2642
+ const agentDefault = params?.agentDefault ?? null;
2643
+ const conversationOverride = params?.conversationOverride ?? null;
2644
+ const defaultInstructions = normalizeAgentBehaviorInstructions(agentDefault?.instructions);
2645
+ const overrideInstructions = normalizeAgentBehaviorInstructions(conversationOverride?.instructions);
2646
+ return {
2647
+ participation: {
2648
+ style: conversationOverride?.participationStyle ?? agentDefault?.participationStyle ?? DEFAULT_POLICY.participation.style,
2649
+ allowAgentToAgent: coalesceBoolean(
2650
+ conversationOverride?.allowAgentToAgent,
2651
+ agentDefault?.allowAgentToAgent,
2652
+ DEFAULT_POLICY.participation.allowAgentToAgent
2653
+ ),
2654
+ allowHumanToAgent: DEFAULT_POLICY.participation.allowHumanToAgent,
2655
+ allowLongRunningCollaboration: coalesceBoolean(
2656
+ conversationOverride?.allowLongRunningCollaboration,
2657
+ agentDefault?.allowLongRunningCollaboration,
2658
+ DEFAULT_POLICY.participation.allowLongRunningCollaboration
2659
+ ),
2660
+ requireMentionForGroupReplies: coalesceBoolean(
2661
+ conversationOverride?.requireMentionForGroupReplies,
2662
+ agentDefault?.requireMentionForGroupReplies,
2663
+ DEFAULT_POLICY.participation.requireMentionForGroupReplies
2664
+ ),
2665
+ maxConsecutiveAgentTurns: conversationOverride?.maxConsecutiveAgentTurns !== void 0 ? conversationOverride.maxConsecutiveAgentTurns ?? null : agentDefault?.maxConsecutiveAgentTurns !== void 0 ? agentDefault.maxConsecutiveAgentTurns ?? null : defaultMaxConsecutiveAgentTurns(params?.conversationType)
2666
+ },
2667
+ instructions: [
2668
+ ...defaultInstructions ? [defaultInstructions] : [],
2669
+ ...overrideInstructions ? [overrideInstructions] : []
2670
+ ],
2671
+ source: {
2672
+ hasAgentDefault: agentDefault != null,
2673
+ hasConversationOverride: conversationOverride != null
2674
+ }
2675
+ };
2676
+ }
2677
+ __name(resolveAgentBehaviorPolicy, "resolveAgentBehaviorPolicy");
2678
+ function toHistorySenderType(message) {
2679
+ if (isMembershipChangeMessage(message)) return null;
2680
+ if (message.senderType !== "ai_agent") {
2681
+ return "human";
2682
+ }
2683
+ return shouldTriggerAgentTurn({
2684
+ senderType: "ai_agent",
2685
+ metadata: message.metadata
2686
+ }).allow ? "ai_agent" : null;
2687
+ }
2688
+ __name(toHistorySenderType, "toHistorySenderType");
2689
+ function buildParticipationHistorySnapshotFromSenderTypes(recentSenderTypes) {
2690
+ let consecutiveAgentTurns = 0;
2691
+ for (const senderType of recentSenderTypes) {
2692
+ if (senderType !== "ai_agent") break;
2693
+ consecutiveAgentTurns += 1;
2694
+ }
2695
+ return {
2696
+ recentSenderTypes,
2697
+ recentHumanCount: recentSenderTypes.filter((senderType) => senderType === "human").length,
2698
+ recentAgentCount: recentSenderTypes.filter((senderType) => senderType === "ai_agent").length,
2699
+ consecutiveAgentTurns,
2700
+ currentAgentStreakStartedByHuman: consecutiveAgentTurns > 0 && recentSenderTypes[consecutiveAgentTurns] === "human"
2701
+ };
2702
+ }
2703
+ __name(buildParticipationHistorySnapshotFromSenderTypes, "buildParticipationHistorySnapshotFromSenderTypes");
2704
+ function buildParticipationHistorySnapshot(messages, agentId) {
2705
+ void agentId;
2706
+ const recentSenderTypes = messages.flatMap((message) => {
2707
+ const senderType = toHistorySenderType(message);
2708
+ return senderType ? [senderType] : [];
2709
+ });
2710
+ return buildParticipationHistorySnapshotFromSenderTypes(recentSenderTypes);
2711
+ }
2712
+ __name(buildParticipationHistorySnapshot, "buildParticipationHistorySnapshot");
2713
+ function evaluateParticipationPolicy(policy, input) {
2714
+ const resolved = policy ?? resolveAgentBehaviorPolicy({ conversationType: input.conversationType });
2715
+ const participation = resolved.participation;
2716
+ const priorAgentTurns = Math.max(input.consecutiveAgentTurns ?? 0, 0);
2717
+ const agentTurnsWithCurrent = priorAgentTurns + (input.senderType === "ai_agent" ? 1 : 0);
2718
+ const consecutiveAgentTurns = Math.max(
2719
+ priorAgentTurns,
2720
+ input.senderType === "ai_agent" ? 1 : 0
2721
+ );
2722
+ const currentAgentStreakStartedByHuman = input.currentAgentStreakStartedByHuman === true;
2723
+ if (input.conversationType === "group" && participation.requireMentionForGroupReplies && !input.mentionedAgent) {
2724
+ return {
2725
+ allow: false,
2726
+ reasonCode: "group_mention_required",
2727
+ reason: "group replies require a direct mention"
2728
+ };
2729
+ }
2730
+ if (input.isOwner) {
2731
+ return {
2732
+ allow: true,
2733
+ reasonCode: "owner_sender",
2734
+ reason: "owner messages pass through outside mention-required group turns"
2735
+ };
2736
+ }
2737
+ if (input.senderType !== "ai_agent") {
2738
+ return { allow: true, reasonCode: "human_sender", reason: "latest sender is human" };
2739
+ }
2740
+ if (!participation.allowAgentToAgent) {
2741
+ return {
2742
+ allow: false,
2743
+ reasonCode: "agent_to_agent_disabled",
2744
+ reason: "agent-to-agent participation is disabled by policy"
2745
+ };
2746
+ }
2747
+ if (!participation.allowLongRunningCollaboration && (consecutiveAgentTurns > 1 || !currentAgentStreakStartedByHuman)) {
2748
+ return {
2749
+ allow: false,
2750
+ reasonCode: "human_reset_required",
2751
+ reason: "a fresh human steer is required before continuing agent collaboration"
2752
+ };
2753
+ }
2754
+ if (typeof participation.maxConsecutiveAgentTurns === "number" && participation.maxConsecutiveAgentTurns >= 0 && agentTurnsWithCurrent >= participation.maxConsecutiveAgentTurns) {
2755
+ return {
2756
+ allow: false,
2757
+ reasonCode: "agent_turn_limit_reached",
2758
+ reason: "maximum consecutive agent turns reached"
2759
+ };
2760
+ }
2761
+ return {
2762
+ allow: true,
2763
+ reasonCode: input.conversationType === "group" ? "group_agent_allowed" : "direct_agent_allowed",
2764
+ reason: participation.requireMentionForGroupReplies ? "policy allows this directly mentioned group reply" : "agent-to-agent participation allowed by policy"
2765
+ };
2279
2766
  }
2280
- __name(formatMembershipChangeNotice, "formatMembershipChangeNotice");
2281
-
2282
- // ../backend-contracts/src/turnProtocol.ts
2283
- var ACTIVE_TURN_STALE_THRESHOLD_MS = 30 * 60 * 1e3;
2284
- var WAITING_INPUT_STALE_THRESHOLD_MS = 12 * 60 * 60 * 1e3;
2767
+ __name(evaluateParticipationPolicy, "evaluateParticipationPolicy");
2285
2768
 
2286
2769
  // ../backend-contracts/src/agentDirectory.ts
2287
2770
  var MAX_DISCOVER_AGENTS_QUERY_LENGTH = 64;
@@ -3681,9 +4164,9 @@ function splitTurnMetadata(metadata) {
3681
4164
  };
3682
4165
  }
3683
4166
  __name(splitTurnMetadata, "splitTurnMetadata");
3684
- function compact(record5) {
4167
+ function compact(record4) {
3685
4168
  const out = {};
3686
- for (const [key, value] of Object.entries(record5)) {
4169
+ for (const [key, value] of Object.entries(record4)) {
3687
4170
  if (value !== void 0) out[key] = value;
3688
4171
  }
3689
4172
  return out;
@@ -3864,12 +4347,12 @@ function parseDirectConversationSelection(value) {
3864
4347
  if (!value || typeof value !== "object" || Array.isArray(value)) {
3865
4348
  throw new Error("selection must be an object");
3866
4349
  }
3867
- const record5 = value;
3868
- if (record5.mode === "latest_or_new" || record5.mode === "new") {
3869
- return { mode: record5.mode };
4350
+ const record4 = value;
4351
+ if (record4.mode === "latest_or_new" || record4.mode === "new") {
4352
+ return { mode: record4.mode };
3870
4353
  }
3871
- if (record5.mode === "specific") {
3872
- const conversationId = typeof record5.conversationId === "string" ? record5.conversationId.trim() : "";
4354
+ if (record4.mode === "specific") {
4355
+ const conversationId = typeof record4.conversationId === "string" ? record4.conversationId.trim() : "";
3873
4356
  if (!conversationId) throw new Error("selection.conversationId is required");
3874
4357
  return { mode: "specific", conversationId };
3875
4358
  }
@@ -4063,6 +4546,14 @@ function normalizePublicRuntimeFacts(value) {
4063
4546
  }
4064
4547
  __name(normalizePublicRuntimeFacts, "normalizePublicRuntimeFacts");
4065
4548
 
4549
+ // ../backend-contracts/src/conversationMembership.ts
4550
+ function resolveConversationPolicyScope(memberIdsOrCount) {
4551
+ const count = Array.isArray(memberIdsOrCount) ? new Set(memberIdsOrCount.filter((id7) => typeof id7 === "string" && id7.length > 0)).size : memberIdsOrCount;
4552
+ if (typeof count !== "number" || !Number.isSafeInteger(count)) return "unknown";
4553
+ return count === 2 ? "direct" : count > 2 ? "group" : "unknown";
4554
+ }
4555
+ __name(resolveConversationPolicyScope, "resolveConversationPolicyScope");
4556
+
4066
4557
  // ../backend-contracts/src/endpointContentPolicy.ts
4067
4558
  var MLS_DEV_UNSUPPORTED_CONTENT_ACTIONS = ["forward_message"];
4068
4559
  var MLS_DEV_DISCLOSED_PROCESSING_FIELDS = {
@@ -4129,6 +4620,7 @@ var ENDPOINT_CONTENT_FUNCTION_QUERIES = [
4129
4620
  "mls_group_controls",
4130
4621
  "mls_group_admissions",
4131
4622
  "mls_interactions",
4623
+ "mls_devices",
4132
4624
  "list_artifacts",
4133
4625
  "get_artifact_log",
4134
4626
  "get_artifact_asset",
@@ -4283,15 +4775,19 @@ var actionRouting = {
4283
4775
  create_conversation: ["memberIds.*"],
4284
4776
  add_member: ["conversationId", "userId", "agentId"],
4285
4777
  remove_member: ["conversationId", "userId", "agentId", "targetUserId"],
4778
+ // A member's role is membership, which Canon sees and enforces in any room (ruling 3).
4286
4779
  leave_conversation: ["conversationId"],
4287
- update_member_role: ["conversationId", "userId", "targetUserId"],
4288
- update_conversation: ["conversationId"],
4289
- rename_conversation: ["conversationId"],
4290
- update_topic: ["conversationId"],
4291
- update_group_avatar: ["conversationId"],
4780
+ update_member_role: ["conversationId", "userId", "targetUserId", "role"],
4781
+ // A room's name, topic and picture are its public details, as in any room: Canon stores and serves them. The picture
4782
+ // names no file: Canon takes its type from `mimeType`.
4783
+ update_conversation: ["conversationId", "name", "topic"],
4784
+ rename_conversation: ["conversationId", "name"],
4785
+ update_topic: ["conversationId", "topic"],
4786
+ update_group_avatar: ["conversationId", "data", "mimeType"],
4292
4787
  mark_read: ["conversationId"],
4293
4788
  cancel_queued_message: ["conversationId", "messageId"],
4294
- set_conversation_preferences: ["conversationId"],
4789
+ // A person's own settings for a room, muting it or hiding it from their list: Canon applies them, as it decides who gets a push.
4790
+ set_conversation_preferences: ["conversationId", "mutedUntil", "deleted"],
4295
4791
  set_block: ["targetUserId"],
4296
4792
  save_contact: ["contactUserId"],
4297
4793
  remove_contact: ["contactId", "contactUserId"],
@@ -4323,10 +4819,21 @@ var actionRouting = {
4323
4819
  consume_runtime_primitive: ["conversationId", "requestId", "expectedRevision"],
4324
4820
  generate_image: ["conversationId", "requestId"],
4325
4821
  update_agent_behavior_policy: ["agentId"],
4326
- update_conversation_agent_behavior_policy: ["conversationId", "agentId"]
4822
+ // A room's rules are settings Canon stores and an encrypted room's runner reads back, so they are metadata; its free-text
4823
+ // `instructions` stay private, which keeps them out of an encrypted room (plaintext-retirement.md §5.5).
4824
+ update_conversation_agent_behavior_policy: [
4825
+ "conversationId",
4826
+ "agentId",
4827
+ "policy.participationStyle",
4828
+ "policy.allowAgentToAgent",
4829
+ "policy.allowLongRunningCollaboration",
4830
+ "policy.requireMentionForGroupReplies",
4831
+ "policy.maxConsecutiveAgentTurns"
4832
+ ]
4327
4833
  };
4328
4834
  var queryRouting = {
4329
4835
  mls_interactions: ["version", "conversationId"],
4836
+ mls_devices: [],
4330
4837
  list_artifacts: ["conversationId", "cursor", "limit"],
4331
4838
  get_artifact_log: ["conversationId", "artifactId", "afterSequence", "cursor", "limit"],
4332
4839
  get_artifact_asset: ["conversationId", "artifactId", "assetId"],
@@ -4428,8 +4935,8 @@ function endpointOperationRequestRetention(action, body, envelope) {
4428
4935
  __name(endpointOperationRequestRetention, "endpointOperationRequestRetention");
4429
4936
  function endpointContentBoundary(lane, name, payload) {
4430
4937
  if (!namesForLane[lane]?.includes(name)) throw new EndpointContentPolicyError(lane, name);
4431
- const record5 = payload && typeof payload === "object" ? payload : void 0;
4432
- if (lane === "query.request" && name === "get_ephemeral" && record5 && !ENDPOINT_CONTENT_EPHEMERAL_FAMILIES.includes(record5.family)) {
4938
+ const record4 = payload && typeof payload === "object" ? payload : void 0;
4939
+ if (lane === "query.request" && name === "get_ephemeral" && record4 && !ENDPOINT_CONTENT_EPHEMERAL_FAMILIES.includes(record4.family)) {
4433
4940
  throw new EndpointContentPolicyError(lane, `${name}/unknown-family`);
4434
4941
  }
4435
4942
  const requestRoutingPaths = (actionRouting[name] ?? []).flatMap((field) => [`body.value.${field}`, `envelope.${field}`]);
@@ -4437,7 +4944,7 @@ function endpointContentBoundary(lane, name, payload) {
4437
4944
  if (path.some((part) => secretSegments.has(part))) return "restricted-secret";
4438
4945
  if (lane === "operation.request" && ["respond_interaction", "sync_phone_contacts"].includes(name) && matches(path, "preparedContent.payload")) return "restricted-secret";
4439
4946
  if (lane === "operation.request" && ["respond_interaction", "sync_phone_contacts"].includes(name) && path[0] === "body" && path[1] === "value" && !publicMatch(path, requestRoutingPaths)) return "restricted-secret";
4440
- if (lane === "operation.receipt" && path[0] === "result" && (["consume_interaction", "respond_interaction"].includes(name) || record5?.resultReference?.kind === "interaction")) return "restricted-secret";
4947
+ if (lane === "operation.receipt" && path[0] === "result" && (["consume_interaction", "respond_interaction"].includes(name) || record4?.resultReference?.kind === "interaction")) return "restricted-secret";
4441
4948
  let selected = payload;
4442
4949
  for (const part of path) selected = selected && typeof selected === "object" && Object.hasOwn(selected, part) ? selected[part] : void 0;
4443
4950
  if (selected !== null && typeof selected === "object") return "private-content";
@@ -4446,7 +4953,7 @@ function endpointContentBoundary(lane, name, payload) {
4446
4953
  if (name === "respond_interaction" && path[0] === "body" && path[1] === "value") return "restricted-secret";
4447
4954
  if (name === "sync_phone_contacts" && path[0] === "body" && path[1] === "value") return "restricted-secret";
4448
4955
  if (name === "verb_execute") {
4449
- const wire4 = record5?.body?.value;
4956
+ const wire4 = record4?.body?.value;
4450
4957
  const spec = VERB_WIRE_ENVELOPE_FIELDS[wire4?.verb];
4451
4958
  if (path[0] === "body" && path[1] === "value") {
4452
4959
  if (path.length === 3 && ["wire", "verb"].includes(path[2])) return "public-metadata";
@@ -4459,7 +4966,7 @@ function endpointContentBoundary(lane, name, payload) {
4459
4966
  }
4460
4967
  } else if (lane === "operation.receipt") {
4461
4968
  if (publicMatch(path, [...protocolPaths, "status", "createdAt", "updatedAt", "error.code", "error.status", "error.retryable", "error.retryAfterMs", "resultError.code", "resultError.status", "resultReference.kind", "resultReference.conversationId", "resultReference.artifactId", "resultReference.assetId", "resultReference.uploadId", "resultReference.sessionId", "resultReference.requestId"])) return "public-metadata";
4462
- if (path[0] === "result" && (name === "consume_interaction" || name === "respond_interaction" || record5?.resultReference?.kind === "interaction")) return "restricted-secret";
4969
+ if (path[0] === "result" && (name === "consume_interaction" || name === "respond_interaction" || record4?.resultReference?.kind === "interaction")) return "restricted-secret";
4463
4970
  } else if (lane === "query.request") {
4464
4971
  if (publicMatch(path, queryRouting[name] ?? [])) return "public-metadata";
4465
4972
  } else if (lane === "query.result" || lane === "ephemeral.result") {
@@ -4491,10 +4998,10 @@ var PreparedContentError = class extends Error {
4491
4998
  __name(this, "PreparedContentError");
4492
4999
  }
4493
5000
  };
4494
- function invalid10() {
5001
+ function invalid12() {
4495
5002
  throw new PreparedContentError("INVALID_PREPARED_CONTENT");
4496
5003
  }
4497
- __name(invalid10, "invalid");
5004
+ __name(invalid12, "invalid");
4498
5005
  var record2 = /* @__PURE__ */ __name((value) => !!value && typeof value === "object" && !Array.isArray(value), "record");
4499
5006
  var keys = /* @__PURE__ */ __name((value, allowed) => Object.keys(value).every((key) => allowed.includes(key)), "keys");
4500
5007
  var revision = /* @__PURE__ */ __name((value) => Number.isSafeInteger(value) && value >= 0, "revision");
@@ -4515,25 +5022,25 @@ function canonicalEndpointJson(value) {
4515
5022
  }
4516
5023
  __name(canonicalEndpointJson, "canonicalEndpointJson");
4517
5024
  function validateMetadata(value) {
4518
- if (!record2(value)) invalid10();
5025
+ if (!record2(value)) invalid12();
4519
5026
  if (value.version !== PREPARED_CONTENT_VERSION) throw new PreparedContentError("UNSUPPORTED_PREPARED_CONTENT_VERSION");
4520
5027
  if (value.codec !== PREPARED_JSON_CODEC) throw new PreparedContentError("UNSUPPORTED_PREPARED_CONTENT_CODEC");
4521
- if (!keys(value, ["version", "context", "codec", "payload", "blobs", "expected"])) invalid10();
5028
+ if (!keys(value, ["version", "context", "codec", "payload", "blobs", "expected"])) invalid12();
4522
5029
  const context = value.context;
4523
- if (!record2(context) || !keys(context, ["action", "conversationId", "messageId"]) || typeof context.action !== "string" || !ENDPOINT_ACTION_PATTERN.test(context.action) || context.conversationId !== void 0 && !identity(context.conversationId) || context.messageId !== void 0 && !identity(context.messageId)) invalid10();
5030
+ if (!record2(context) || !keys(context, ["action", "conversationId", "messageId"]) || typeof context.action !== "string" || !ENDPOINT_ACTION_PATTERN.test(context.action) || context.conversationId !== void 0 && !identity(context.conversationId) || context.messageId !== void 0 && !identity(context.messageId)) invalid12();
4524
5031
  const expected = value.expected;
4525
- if (!record2(expected) || !keys(expected, ["installationGeneration", "protocolRevision", "admission"]) || !revision(expected.installationGeneration) || !revision(expected.protocolRevision)) invalid10();
5032
+ if (!record2(expected) || !keys(expected, ["installationGeneration", "protocolRevision", "admission"]) || !revision(expected.installationGeneration) || !revision(expected.protocolRevision)) invalid12();
4526
5033
  if (expected.admission !== void 0) {
4527
5034
  const admission = expected.admission;
4528
- if (!record2(admission) || !keys(admission, ["conversationId", "membershipRevision", "admissionId", "targetAdmissionId"]) || ["conversationId", "admissionId", "targetAdmissionId"].some((key) => admission[key] !== void 0 && !identity(admission[key])) || admission.membershipRevision !== void 0 && !revision(admission.membershipRevision) || context.conversationId !== void 0 && admission.conversationId !== void 0 && admission.conversationId !== context.conversationId) invalid10();
5035
+ if (!record2(admission) || !keys(admission, ["conversationId", "membershipRevision", "admissionId", "targetAdmissionId"]) || ["conversationId", "admissionId", "targetAdmissionId"].some((key) => admission[key] !== void 0 && !identity(admission[key])) || admission.membershipRevision !== void 0 && !revision(admission.membershipRevision) || context.conversationId !== void 0 && admission.conversationId !== void 0 && admission.conversationId !== context.conversationId) invalid12();
4529
5036
  }
4530
- if (!Array.isArray(value.blobs)) invalid10();
5037
+ if (!Array.isArray(value.blobs)) invalid12();
4531
5038
  const ids = /* @__PURE__ */ new Set();
4532
5039
  for (const [index, blob] of value.blobs.entries()) {
4533
- if (!record2(blob) || !keys(blob, ["id", "index"]) || !blobIdentity(blob.id) || blob.index !== index || ids.has(blob.id)) invalid10();
5040
+ if (!record2(blob) || !keys(blob, ["id", "index"]) || !blobIdentity(blob.id) || blob.index !== index || ids.has(blob.id)) invalid12();
4534
5041
  ids.add(blob.id);
4535
5042
  }
4536
- if (typeof value.payload !== "string") invalid10();
5043
+ if (typeof value.payload !== "string") invalid12();
4537
5044
  }
4538
5045
  __name(validateMetadata, "validateMetadata");
4539
5046
  function decodePreparedJsonContent(value) {
@@ -4542,10 +5049,10 @@ function decodePreparedJsonContent(value) {
4542
5049
  try {
4543
5050
  decoded = JSON.parse(value.payload);
4544
5051
  } catch {
4545
- invalid10();
5052
+ invalid12();
4546
5053
  }
4547
- if (!record2(decoded) || !keys(decoded, ["body", "envelope"]) || !record2(decoded.body) || decoded.envelope !== void 0 && !record2(decoded.envelope)) invalid10();
4548
- if (canonicalEndpointJson(decoded) !== value.payload) invalid10();
5054
+ if (!record2(decoded) || !keys(decoded, ["body", "envelope"]) || !record2(decoded.body) || decoded.envelope !== void 0 && !record2(decoded.envelope)) invalid12();
5055
+ if (canonicalEndpointJson(decoded) !== value.payload) invalid12();
4549
5056
  const { body, envelope } = decoded;
4550
5057
  if (endpointOperationRequestRetention(value.context.action, body, envelope) === "memory") {
4551
5058
  throw new PreparedContentError("PREPARED_CONTENT_MEMORY_ONLY");
@@ -4553,7 +5060,7 @@ function decodePreparedJsonContent(value) {
4553
5060
  const effective = { ...body, ...envelope };
4554
5061
  for (const key of ["conversationId", "messageId"]) {
4555
5062
  const bound = value.context[key];
4556
- if (bound !== void 0 && effective[key] !== void 0 && effective[key] !== bound) invalid10();
5063
+ if (bound !== void 0 && effective[key] !== void 0 && effective[key] !== bound) invalid12();
4557
5064
  }
4558
5065
  return envelope === void 0 ? { body } : { body, envelope };
4559
5066
  }
@@ -4583,7 +5090,7 @@ function prepareJsonContent(input) {
4583
5090
  }
4584
5091
  __name(prepareJsonContent, "prepareJsonContent");
4585
5092
  function logicalMediaBlobId(conversationId, messageId2, index) {
4586
- if (!identity(conversationId) || !identity(messageId2) || !revision(index)) invalid10();
5093
+ if (!identity(conversationId) || !identity(messageId2) || !revision(index)) invalid12();
4587
5094
  return JSON.stringify([conversationId, messageId2, index]);
4588
5095
  }
4589
5096
  __name(logicalMediaBlobId, "logicalMediaBlobId");
@@ -4626,31 +5133,31 @@ var ConnectorRelayRequestError = class extends Error {
4626
5133
  }
4627
5134
  name = "ConnectorRelayRequestError";
4628
5135
  };
4629
- function invalid11(what) {
5136
+ function invalid13(what) {
4630
5137
  throw new ConnectorRelayRequestError(`Invalid relay request: ${what}`);
4631
5138
  }
4632
- __name(invalid11, "invalid");
5139
+ __name(invalid13, "invalid");
4633
5140
  function record3(value, required, optional = []) {
4634
- if (!value || typeof value !== "object" || Array.isArray(value)) invalid11("expected an object");
5141
+ if (!value || typeof value !== "object" || Array.isArray(value)) invalid13("expected an object");
4635
5142
  const result = value;
4636
- for (const key of Object.keys(result)) if (!required.includes(key) && !optional.includes(key)) invalid11(`unexpected ${key}`);
4637
- for (const key of required) if (!Object.hasOwn(result, key)) invalid11(`missing ${key}`);
5143
+ for (const key of Object.keys(result)) if (!required.includes(key) && !optional.includes(key)) invalid13(`unexpected ${key}`);
5144
+ for (const key of required) if (!Object.hasOwn(result, key)) invalid13(`missing ${key}`);
4638
5145
  return result;
4639
5146
  }
4640
5147
  __name(record3, "record");
4641
5148
  function id6(value, what, pattern = ENDPOINT_ID_PATTERN) {
4642
- if (typeof value !== "string" || !pattern.test(value)) invalid11(what);
5149
+ if (typeof value !== "string" || !pattern.test(value)) invalid13(what);
4643
5150
  return value;
4644
5151
  }
4645
5152
  __name(id6, "id");
4646
5153
  function doc(value, what) {
4647
- if (typeof value !== "string" || !value || value.length > 200 || value.includes("/")) invalid11(what);
5154
+ if (typeof value !== "string" || !value || value.length > 200 || value.includes("/")) invalid13(what);
4648
5155
  return value;
4649
5156
  }
4650
5157
  __name(doc, "doc");
4651
5158
  var room = /* @__PURE__ */ __name((value) => doc(value, "conversationId"), "room");
4652
5159
  function text4(value) {
4653
- if (typeof value !== "string" || !value.trim() || new TextEncoder().encode(value).length > CONNECTOR_RELAY_MAX_TEXT_BYTES) invalid11("text");
5160
+ if (typeof value !== "string" || !value.trim() || new TextEncoder().encode(value).length > CONNECTOR_RELAY_MAX_TEXT_BYTES) invalid13("text");
4654
5161
  return value;
4655
5162
  }
4656
5163
  __name(text4, "text");
@@ -4658,18 +5165,18 @@ function selection(value) {
4658
5165
  const args = record3(value, ["mode"], ["conversationId"]);
4659
5166
  if ((args.mode === "new" || args.mode === "latest_or_new") && args.conversationId === void 0) return { mode: args.mode };
4660
5167
  if (args.mode === "specific") return { mode: "specific", conversationId: room(args.conversationId) };
4661
- return invalid11("selection");
5168
+ return invalid13("selection");
4662
5169
  }
4663
5170
  __name(selection, "selection");
4664
5171
  function limit(value) {
4665
5172
  if (value === void 0) return void 0;
4666
- if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1 || value > 100) invalid11("limit");
5173
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1 || value > 100) invalid13("limit");
4667
5174
  return value;
4668
5175
  }
4669
5176
  __name(limit, "limit");
4670
5177
  function parseConnectorRelayRequest(value) {
4671
5178
  const body = record3(value, ["version", "agentId", "grantId", "op", "args"]);
4672
- if (body.version !== 1) invalid11("version");
5179
+ if (body.version !== 1) invalid13("version");
4673
5180
  const head = { version: 1, agentId: doc(body.agentId, "agentId"), grantId: id6(body.grantId, "grantId") };
4674
5181
  switch (body.op) {
4675
5182
  case "pending": {
@@ -4690,7 +5197,7 @@ function parseConnectorRelayRequest(value) {
4690
5197
  }
4691
5198
  case "settle": {
4692
5199
  const args = record3(body.args, ["inputId", "requestId", "outcome"]);
4693
- if (!["completed", "no_reply", "failed"].includes(args.outcome)) invalid11("outcome");
5200
+ if (!["completed", "no_reply", "failed"].includes(args.outcome)) invalid13("outcome");
4694
5201
  return { ...head, op: "settle", args: {
4695
5202
  inputId: id6(args.inputId, "inputId", CONNECTOR_RELAY_INPUT_ID_PATTERN),
4696
5203
  requestId: id6(args.requestId, "requestId"),
@@ -4699,7 +5206,7 @@ function parseConnectorRelayRequest(value) {
4699
5206
  }
4700
5207
  case "read": {
4701
5208
  const args = record3(body.args, ["conversationId"], ["limit", "before"]);
4702
- if (args.before !== void 0 && (typeof args.before !== "string" || !/^[1-9][0-9]{0,15}$/.test(args.before))) invalid11("before");
5209
+ if (args.before !== void 0 && (typeof args.before !== "string" || !/^[1-9][0-9]{0,15}$/.test(args.before))) invalid13("before");
4703
5210
  return { ...head, op: "read", args: {
4704
5211
  conversationId: room(args.conversationId),
4705
5212
  ...args.limit === void 0 ? {} : { limit: limit(args.limit) },
@@ -4721,8 +5228,8 @@ function parseConnectorRelayRequest(value) {
4721
5228
  }
4722
5229
  case "credential": {
4723
5230
  const args = record3(body.args, ["installationId", "generation", "credential"]);
4724
- if (!Number.isSafeInteger(args.generation) || args.generation < 1) invalid11("generation");
4725
- if (!isConnectorRelayCredential(args.credential)) invalid11("credential");
5231
+ if (!Number.isSafeInteger(args.generation) || args.generation < 1) invalid13("generation");
5232
+ if (!isConnectorRelayCredential(args.credential)) invalid13("credential");
4726
5233
  return { ...head, op: "credential", args: {
4727
5234
  installationId: id6(args.installationId, "installationId", CONNECTOR_RELAY_INSTALLATION_PATTERN),
4728
5235
  generation: args.generation,
@@ -4730,7 +5237,7 @@ function parseConnectorRelayRequest(value) {
4730
5237
  } };
4731
5238
  }
4732
5239
  default:
4733
- return invalid11("op");
5240
+ return invalid13("op");
4734
5241
  }
4735
5242
  }
4736
5243
  __name(parseConnectorRelayRequest, "parseConnectorRelayRequest");
@@ -4804,231 +5311,6 @@ var ARTIFACT_LIMITS = Object.freeze({
4804
5311
  });
4805
5312
  var NUMBER_MAX_TEXT = String(ARTIFACT_LIMITS.formNumberMax).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
4806
5313
 
4807
- // ../backend-contracts/src/mlsDevCredentialReconciliation.ts
4808
- var MLS_DEV_CREDENTIAL_RECONCILIATION_CHALLENGE_TTL_MS = 3e5;
4809
- var MLS_DEV_CREDENTIAL_RECONCILIATION_MAX_BYTES = 8192;
4810
- var MlsDevCredentialReconciliationValidationError = class extends Error {
4811
- static {
4812
- __name(this, "MlsDevCredentialReconciliationValidationError");
4813
- }
4814
- code = "INVALID_MLS_DEV_CREDENTIAL_RECONCILIATION";
4815
- constructor() {
4816
- super("INVALID_MLS_DEV_CREDENTIAL_RECONCILIATION");
4817
- this.name = "MlsDevCredentialReconciliationValidationError";
4818
- }
4819
- };
4820
- var utf86 = new TextEncoder();
4821
- var domain2 = utf86.encode("canon.mls.credential-reconciliation-proof.v1\0");
4822
- function invalid12() {
4823
- throw new MlsDevCredentialReconciliationValidationError();
4824
- }
4825
- __name(invalid12, "invalid");
4826
- function boundary9(read) {
4827
- try {
4828
- return read();
4829
- } catch {
4830
- return invalid12();
4831
- }
4832
- }
4833
- __name(boundary9, "boundary");
4834
- function bounded7(value) {
4835
- if (utf86.encode(JSON.stringify(value)).length > MLS_DEV_CREDENTIAL_RECONCILIATION_MAX_BYTES) invalid12();
4836
- return Object.freeze(value);
4837
- }
4838
- __name(bounded7, "bounded");
4839
- function encoded6(value, bytes) {
4840
- decodeCanonicalMlsBase64Url(value, bytes);
4841
- return value;
4842
- }
4843
- __name(encoded6, "encoded");
4844
- function parseMlsDevCredentialReconciliationBegin(value) {
4845
- return boundary9(() => {
4846
- const input = readMlsDataRecord(value, ["version", "deviceId", "requestId", "expectedCredentialGeneration"]);
4847
- return bounded7({
4848
- version: requireMlsLiteral(input.version, 1),
4849
- deviceId: requireMlsUuid(input.deviceId),
4850
- requestId: requireMlsUuid(input.requestId),
4851
- expectedCredentialGeneration: requireMlsInteger(input.expectedCredentialGeneration)
4852
- });
4853
- });
4854
- }
4855
- __name(parseMlsDevCredentialReconciliationBegin, "parseMlsDevCredentialReconciliationBegin");
4856
- function parseMlsDevCredentialReconciliationChallenge(value) {
4857
- return boundary9(() => {
4858
- const input = readMlsDataRecord(value, [
4859
- "version",
4860
- "challengeId",
4861
- "requestId",
4862
- "nonce",
4863
- "device",
4864
- "expectedCredentialGeneration",
4865
- "issuedAtMs",
4866
- "expiresAtMs"
4867
- ]);
4868
- const device = parseMlsDevEnrollmentResult({ version: 1, authorization: "registration_only", device: input.device }).device;
4869
- const issuedAtMs = requireMlsInteger(input.issuedAtMs), expiresAtMs = requireMlsInteger(input.expiresAtMs);
4870
- if (issuedAtMs < device.registeredAtMs || expiresAtMs - issuedAtMs !== MLS_DEV_CREDENTIAL_RECONCILIATION_CHALLENGE_TTL_MS) invalid12();
4871
- return bounded7({
4872
- version: requireMlsLiteral(input.version, 1),
4873
- challengeId: requireMlsUuid(input.challengeId),
4874
- requestId: requireMlsUuid(input.requestId),
4875
- nonce: encoded6(input.nonce, 32),
4876
- device,
4877
- expectedCredentialGeneration: requireMlsInteger(input.expectedCredentialGeneration),
4878
- issuedAtMs,
4879
- expiresAtMs
4880
- });
4881
- });
4882
- }
4883
- __name(parseMlsDevCredentialReconciliationChallenge, "parseMlsDevCredentialReconciliationChallenge");
4884
- function parseMlsDevCredentialReconciliationComplete(value) {
4885
- return boundary9(() => {
4886
- const input = readMlsDataRecord(value, ["version", "challengeId", "proof"]);
4887
- return bounded7({ version: requireMlsLiteral(input.version, 1), challengeId: requireMlsUuid(input.challengeId), proof: encoded6(input.proof, 64) });
4888
- });
4889
- }
4890
- __name(parseMlsDevCredentialReconciliationComplete, "parseMlsDevCredentialReconciliationComplete");
4891
- function parseMlsDevCredentialReconciliationReceipt(value) {
4892
- return boundary9(() => {
4893
- const input = readMlsDataRecord(value, ["version", "authorization", "challenge", "observedCredentialGeneration", "observedAtMs"]);
4894
- const challenge = parseMlsDevCredentialReconciliationChallenge(input.challenge);
4895
- const observedCredentialGeneration = requireMlsInteger(input.observedCredentialGeneration), observedAtMs = requireMlsInteger(input.observedAtMs);
4896
- if (observedCredentialGeneration < challenge.expectedCredentialGeneration || observedAtMs < challenge.issuedAtMs || observedAtMs >= challenge.expiresAtMs) invalid12();
4897
- return bounded7({
4898
- version: requireMlsLiteral(input.version, 1),
4899
- authorization: requireMlsLiteral(input.authorization, "credential_generation_observation_only"),
4900
- challenge,
4901
- observedCredentialGeneration,
4902
- observedAtMs
4903
- });
4904
- });
4905
- }
4906
- __name(parseMlsDevCredentialReconciliationReceipt, "parseMlsDevCredentialReconciliationReceipt");
4907
-
4908
- // ../backend-contracts/src/mlsDevDeviceCustody.ts
4909
- var MLS_DEV_DEVICE_CONTEXT_MAX_BYTES = 2048;
4910
- var MLS_DEV_DEVICE_COMMAND_MAX_BYTES = 16384;
4911
- var MLS_DEV_DEVICE_WRAPPED_STATE_MAX_BYTES = 6144;
4912
- var MlsDevDeviceCustodyValidationError = class extends Error {
4913
- static {
4914
- __name(this, "MlsDevDeviceCustodyValidationError");
4915
- }
4916
- code = "INVALID_MLS_DEV_DEVICE_CUSTODY";
4917
- constructor() {
4918
- super("INVALID_MLS_DEV_DEVICE_CUSTODY");
4919
- this.name = "MlsDevDeviceCustodyValidationError";
4920
- }
4921
- };
4922
- var utf87 = new TextEncoder();
4923
- function invalid13() {
4924
- throw new MlsDevDeviceCustodyValidationError();
4925
- }
4926
- __name(invalid13, "invalid");
4927
- function boundary10(read) {
4928
- try {
4929
- return read();
4930
- } catch {
4931
- return invalid13();
4932
- }
4933
- }
4934
- __name(boundary10, "boundary");
4935
- function bounded8(value, limit2) {
4936
- if (utf87.encode(JSON.stringify(value)).length > limit2) invalid13();
4937
- return Object.freeze(value);
4938
- }
4939
- __name(bounded8, "bounded");
4940
- function binding2(input) {
4941
- return {
4942
- version: requireMlsLiteral(input.version, 1),
4943
- environmentId: requireMlsEnvironmentId(input.environmentId),
4944
- principal: parseMlsDevEnrollmentPrincipal(input.principal),
4945
- installationId: parseMlsDevInstallationId(input.installationId)
4946
- };
4947
- }
4948
- __name(binding2, "binding");
4949
- function parseMlsDevDeviceBinding(value) {
4950
- return boundary10(() => bounded8(binding2(readMlsDataRecord(value, ["version", "environmentId", "principal", "installationId"])), MLS_DEV_DEVICE_CONTEXT_MAX_BYTES));
4951
- }
4952
- __name(parseMlsDevDeviceBinding, "parseMlsDevDeviceBinding");
4953
- function parseMlsDevDeviceContext(value) {
4954
- return boundary10(() => {
4955
- const input = readMlsDataRecord(value, ["version", "environmentId", "principal", "installationId", "revision"]);
4956
- const revision2 = requireMlsInteger(input.revision);
4957
- if (revision2 >= Number.MAX_SAFE_INTEGER) invalid13();
4958
- return bounded8({ ...binding2(input), revision: revision2 }, MLS_DEV_DEVICE_CONTEXT_MAX_BYTES);
4959
- });
4960
- }
4961
- __name(parseMlsDevDeviceContext, "parseMlsDevDeviceContext");
4962
- function parseMlsDevDeviceCommand(value) {
4963
- return boundary10(() => {
4964
- if (value === null || typeof value !== "object") invalid13();
4965
- const descriptor = Object.getOwnPropertyDescriptor(value, "op");
4966
- if (!descriptor || !Object.hasOwn(descriptor, "value")) invalid13();
4967
- if (descriptor.value === "create") {
4968
- const input2 = readMlsDataRecord(value, ["op"]);
4969
- return Object.freeze({ op: requireMlsLiteral(input2.op, "create") });
4970
- }
4971
- if (descriptor.value === "enrollment_proof") {
4972
- const input2 = readMlsDataRecord(value, ["op", "challenge"]);
4973
- return bounded8({
4974
- op: requireMlsLiteral(input2.op, "enrollment_proof"),
4975
- challenge: parseMlsDevEnrollmentChallenge(input2.challenge)
4976
- }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
4977
- }
4978
- if (descriptor.value === "credential_reconciliation_proof") {
4979
- const input2 = readMlsDataRecord(value, ["op", "challenge", "expectedCredentialGeneration"]);
4980
- const challenge2 = parseMlsDevCredentialReconciliationChallenge(input2.challenge);
4981
- const expectedCredentialGeneration2 = requireMlsInteger(input2.expectedCredentialGeneration);
4982
- if (challenge2.expectedCredentialGeneration !== expectedCredentialGeneration2) invalid13();
4983
- return bounded8({
4984
- op: requireMlsLiteral(input2.op, "credential_reconciliation_proof"),
4985
- challenge: challenge2,
4986
- expectedCredentialGeneration: expectedCredentialGeneration2
4987
- }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
4988
- }
4989
- if (descriptor.value !== "credential_proof") invalid13();
4990
- const input = readMlsDataRecord(value, ["op", "challenge", "registrationResult", "expectedCredentialGeneration"]);
4991
- const challenge = parseMlsDevCredentialChallenge(input.challenge);
4992
- const registrationResult = parseMlsDevEnrollmentResult(input.registrationResult);
4993
- const expectedCredentialGeneration = requireMlsInteger(input.expectedCredentialGeneration);
4994
- if (expectedCredentialGeneration >= Number.MAX_SAFE_INTEGER || challenge.credential.claims.generation !== expectedCredentialGeneration + 1 || JSON.stringify(challenge.credential.claims.device) !== JSON.stringify(registrationResult.device)) invalid13();
4995
- return bounded8({
4996
- op: requireMlsLiteral(input.op, "credential_proof"),
4997
- challenge,
4998
- registrationResult,
4999
- expectedCredentialGeneration
5000
- }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
5001
- });
5002
- }
5003
- __name(parseMlsDevDeviceCommand, "parseMlsDevDeviceCommand");
5004
- function encoded7(value, bytes) {
5005
- decodeCanonicalMlsBase64Url(value, bytes);
5006
- return value;
5007
- }
5008
- __name(encoded7, "encoded");
5009
- function wrapped(value) {
5010
- if (typeof value !== "string" || value.length > MLS_DEV_DEVICE_WRAPPED_STATE_MAX_BYTES || !value.startsWith("v1:")) invalid13();
5011
- const body = value.slice(3);
5012
- if (body.length < 40 || body.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(body)) invalid13();
5013
- const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
5014
- if (body.endsWith("==") && (alphabet.indexOf(body.at(-3)) & 15) !== 0) invalid13();
5015
- if (!body.endsWith("==") && body.endsWith("=") && (alphabet.indexOf(body.at(-2)) & 3) !== 0) invalid13();
5016
- return value;
5017
- }
5018
- __name(wrapped, "wrapped");
5019
- function parseMlsDevDevicePreparation(value, op) {
5020
- return boundary10(() => {
5021
- if (!["create", "enrollment_proof", "credential_proof", "credential_reconciliation_proof"].includes(op)) invalid13();
5022
- const input = readMlsDataRecord(value, ["wrappedState", "payload"]);
5023
- const payload = readMlsDataRecord(input.payload, op === "create" ? ["signaturePublicKey"] : ["signaturePublicKey", "proof"]);
5024
- return bounded8({ wrappedState: wrapped(input.wrappedState), payload: Object.freeze({
5025
- signaturePublicKey: encoded7(payload.signaturePublicKey, 32),
5026
- ...op === "create" ? {} : { proof: encoded7(payload.proof, 64) }
5027
- }) }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
5028
- });
5029
- }
5030
- __name(parseMlsDevDevicePreparation, "parseMlsDevDevicePreparation");
5031
-
5032
5314
  // ../backend-contracts/src/mlsDevKeyPackage.ts
5033
5315
  var MLS_DEV_KEY_PACKAGE_COMMAND_MAX_BYTES = 16384;
5034
5316
  var MLS_DEV_KEY_PACKAGE_WIRE_MAX_BYTES = 16384;
@@ -5122,7 +5404,7 @@ function parseMlsDevKeyPackagePayload(value) {
5122
5404
  "expiresAtMs"
5123
5405
  ]);
5124
5406
  const notBeforeMs = requireMlsInteger(input.notBeforeMs), expiresAtMs = requireMlsInteger(input.expiresAtMs);
5125
- if (notBeforeMs % 1e3 !== 0 || expiresAtMs % 1e3 !== 0 || expiresAtMs <= notBeforeMs || expiresAtMs - notBeforeMs > 864e5) invalid14();
5407
+ if (notBeforeMs % 1e3 !== 0 || expiresAtMs % 1e3 !== 0 || expiresAtMs <= notBeforeMs || expiresAtMs - notBeforeMs > MLS_DEV_CREDENTIAL_LONG_TTL_MS) invalid14();
5126
5408
  return bounded9({
5127
5409
  version: requireMlsLiteral(input.version, 1),
5128
5410
  keyPackageId: requireMlsUuid(input.keyPackageId),
@@ -5218,103 +5500,6 @@ function parseMlsRoomIdentities(value) {
5218
5500
  }
5219
5501
  __name(parseMlsRoomIdentities, "parseMlsRoomIdentities");
5220
5502
 
5221
- // ../endpoint/src/runtime-api-origins.generated.ts
5222
- var RUNTIME_API_ORIGINS = {
5223
- "canon-dev-v1": "https://dev.api.canonmail.com",
5224
- "canon-prod-v1": "https://api.canonmail.com"
5225
- };
5226
-
5227
- // ../endpoint/src/mls-crypto.ts
5228
- function mlsDevDeviceHttpConfiguration(environmentId) {
5229
- if (!isMlsEnvironmentId(environmentId)) invalid16();
5230
- const origin = RUNTIME_API_ORIGINS[environmentId];
5231
- return Object.freeze({
5232
- enrollmentUrl: `${origin}/mls/enrollment`,
5233
- credentialUrl: `${origin}/mls/credential`,
5234
- reconciliationUrl: `${origin}/mls/reconciliation`,
5235
- keyPackagesUrl: `${origin}/mls/key-packages`,
5236
- trustedOrigins: Object.freeze([origin])
5237
- });
5238
- }
5239
- __name(mlsDevDeviceHttpConfiguration, "mlsDevDeviceHttpConfiguration");
5240
- function invalid16() {
5241
- throw new Error("MLS_DEV_CLIENT_CONFIGURATION_INVALID");
5242
- }
5243
- __name(invalid16, "invalid");
5244
- function record4(value, keys2) {
5245
- if (!value || typeof value !== "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) invalid16();
5246
- const fields2 = Object.getOwnPropertyDescriptors(value);
5247
- if (Reflect.ownKeys(fields2).length !== keys2.length || keys2.some((key) => !Object.hasOwn(fields2, key) || !Object.hasOwn(fields2[key], "value"))) invalid16();
5248
- return value;
5249
- }
5250
- __name(record4, "record");
5251
- function primeOrderPoint(value) {
5252
- const point = ed25519.Point.fromBytes(value, false);
5253
- return !point.isSmallOrder() && point.isTorsionFree();
5254
- }
5255
- __name(primeOrderPoint, "primeOrderPoint");
5256
- function issuerKeys(value, environmentId, receipt = false) {
5257
- if (!Array.isArray(value) || value.length < 1 || value.length > 8) invalid16();
5258
- const seen = /* @__PURE__ */ new Set();
5259
- let environment = environmentId;
5260
- return Object.freeze(Array.from(value, (item2) => {
5261
- const key = record4(item2, ["keyVersion", "signaturePublicKey"]);
5262
- const keyVersion = receipt ? parseMlsDevReceiptKeyVersion(key.keyVersion, environment) : parseMlsDevIssuerKeyVersion(key.keyVersion, environment);
5263
- environment ??= receipt ? mlsEnvironmentOfReceiptKeyVersion(keyVersion) : mlsEnvironmentOfIssuerKeyVersion(keyVersion);
5264
- if (seen.has(keyVersion) || typeof key.signaturePublicKey !== "string" || !primeOrderPoint(decodeCanonicalMlsBase64Url(key.signaturePublicKey, 32))) invalid16();
5265
- seen.add(keyVersion);
5266
- return Object.freeze({ keyVersion, signaturePublicKey: key.signaturePublicKey });
5267
- }));
5268
- }
5269
- __name(issuerKeys, "issuerKeys");
5270
- function parseMlsDevClientConfiguration(value) {
5271
- try {
5272
- const listed = !!value && typeof value === "object" && Object.hasOwn(value, "principalIds");
5273
- const input = record4(value, ["version", "environmentId", "enabled", ...listed ? ["principalIds"] : [], "issuerKeys", "receiptKeys"]);
5274
- if (input.version !== 1 || !isMlsEnvironmentId(input.environmentId) || input.enabled !== true || listed && (!Array.isArray(input.principalIds) || input.principalIds.length < 1 || input.principalIds.length > 100)) invalid16();
5275
- const environmentId = input.environmentId;
5276
- const principalIds = listed ? Array.from(input.principalIds, (id7) => parseMlsDevEnrollmentPrincipal({ type: "human", id: id7 }).id) : void 0;
5277
- if (principalIds && new Set(principalIds).size !== principalIds.length) invalid16();
5278
- return Object.freeze({
5279
- version: 1,
5280
- environmentId,
5281
- enabled: true,
5282
- ...principalIds ? { principalIds: Object.freeze(principalIds) } : {},
5283
- issuerKeys: issuerKeys(input.issuerKeys, environmentId),
5284
- receiptKeys: issuerKeys(input.receiptKeys, environmentId, true)
5285
- });
5286
- } catch {
5287
- return invalid16();
5288
- }
5289
- }
5290
- __name(parseMlsDevClientConfiguration, "parseMlsDevClientConfiguration");
5291
- function createMlsDevCredentialVerifier(options) {
5292
- let trusted;
5293
- try {
5294
- trusted = new Map(issuerKeys(options.issuerKeys).map((key) => [key.keyVersion, key.signaturePublicKey]));
5295
- } catch {
5296
- return invalid16();
5297
- }
5298
- const clock = options.clock ?? Date.now;
5299
- return async (value) => {
5300
- try {
5301
- const receipt = parseMlsDevCredentialReceipt(value);
5302
- const parsed = parseMlsDevCredentialToken(receipt.credential);
5303
- const key = trusted.get(parsed.unsigned.keyVersion);
5304
- const now = clock();
5305
- const { issuedAtMs, expiresAtMs } = parsed.unsigned.claims;
5306
- if (!key || !Number.isSafeInteger(now) || now < issuedAtMs || now >= expiresAtMs) return false;
5307
- const publicKey = decodeCanonicalMlsBase64Url(key, 32);
5308
- const signature = decodeCanonicalMlsBase64Url(parsed.signature, 64);
5309
- if (!primeOrderPoint(publicKey) || !primeOrderPoint(signature.subarray(0, 32))) return false;
5310
- return ed25519.verify(signature, new TextEncoder().encode(parsed.signingInput), publicKey, { zip215: false });
5311
- } catch {
5312
- return false;
5313
- }
5314
- };
5315
- }
5316
- __name(createMlsDevCredentialVerifier, "createMlsDevCredentialVerifier");
5317
-
5318
5503
  export {
5319
5504
  __name,
5320
5505
  getCanonEnvironmentContract,
@@ -5328,6 +5513,8 @@ export {
5328
5513
  isCanonUploadUrl,
5329
5514
  resolveAllowedUploadMimeType,
5330
5515
  isMlsEnvironmentId,
5516
+ mlsEnvironmentOfIssuerKeyVersion,
5517
+ mlsEnvironmentOfReceiptKeyVersion,
5331
5518
  MLS_DEV_ENROLLMENT_MAX_BYTES,
5332
5519
  parseMlsDevEnrollmentPrincipal,
5333
5520
  parseMlsDevEnrollmentBegin,
@@ -5335,7 +5522,9 @@ export {
5335
5522
  parseMlsDevEnrollmentChallenge,
5336
5523
  parseMlsDevEnrollmentResult,
5337
5524
  encodeCanonicalMlsBase64Url,
5525
+ decodeCanonicalMlsBase64Url,
5338
5526
  MLS_DEV_CREDENTIAL_MAX_BYTES,
5527
+ parseMlsDevIssuerKeyVersion,
5339
5528
  parseMlsDevCredentialChallenge,
5340
5529
  parseMlsDevCredentialBegin,
5341
5530
  parseMlsDevCredentialComplete,
@@ -5344,6 +5533,7 @@ export {
5344
5533
  createMlsDevCredentialSigningInput,
5345
5534
  parseMlsDevCredentialToken,
5346
5535
  parseMlsDevCredentialReceipt,
5536
+ parseMlsDevReceiptKeyVersion,
5347
5537
  MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW,
5348
5538
  isMlsDevReceiptClockSkew,
5349
5539
  parseMlsDevGroupFeedEntry,
@@ -5366,6 +5556,7 @@ export {
5366
5556
  parseMlsDevGroupHead,
5367
5557
  parseMlsDevGroupMarker,
5368
5558
  parseMlsDevGroupRoster,
5559
+ mlsAdmissionWait,
5369
5560
  parseMlsDevRoomRemoval,
5370
5561
  parseMlsDevGroupControl,
5371
5562
  parseMlsDevGroupAcceptedControl,
@@ -5388,8 +5579,10 @@ export {
5388
5579
  RUNTIME_CARD_LINE_ITEM_COLUMN_TYPES,
5389
5580
  readMembershipChangeMetadata,
5390
5581
  formatMembershipChangeNotice,
5582
+ PARTICIPATION_HISTORY_FETCH_LIMIT,
5583
+ buildParticipationHistorySnapshot,
5584
+ evaluateParticipationPolicy,
5391
5585
  MAX_DISCOVER_AGENTS_QUERY_LENGTH,
5392
- VERB_LIMITS,
5393
5586
  NO_REPLY_ACK_NOTE,
5394
5587
  CANON_VERB_WIRE_SCHEMA_VERSION,
5395
5588
  projectVerbIntentToWire,
@@ -5399,6 +5592,7 @@ export {
5399
5592
  MAX_PUBLIC_RUNTIME_COMMANDS,
5400
5593
  normalizePublicRuntimeDescriptor,
5401
5594
  normalizePublicRuntimeFacts,
5595
+ resolveConversationPolicyScope,
5402
5596
  MLS_DEV_UNSUPPORTED_CONTENT_ACTIONS,
5403
5597
  MLS_DEV_DISCLOSED_PROCESSING_FIELDS,
5404
5598
  endpointOperationRequestRetention,
@@ -5442,8 +5636,5 @@ export {
5442
5636
  isMlsPrincipalAlias,
5443
5637
  parseMlsPrincipalOpening,
5444
5638
  encodeMlsPrincipalAliasInput,
5445
- parseMlsRoomIdentities,
5446
- mlsDevDeviceHttpConfiguration,
5447
- parseMlsDevClientConfiguration,
5448
- createMlsDevCredentialVerifier
5639
+ parseMlsRoomIdentities
5449
5640
  };