@byok-sdk/cloud 0.8.0 → 0.9.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { BOARD_STATUSES, CapabilityDeclarationSchema, NONCE_SIGNING_DOMAIN, hasCapability, isTenantId, tenantId, principalTenant, parseDeviceProofEnvelope, deviceProofSigningInput, contentHash, parseCapabilityDeclaration, ByokCoreError, tenantKey, PRESENCE_LEVELS, createInMemoryCoreStores, authenticateDeviceAssertion, assertCapability, isCoreConflictError, isCoreError, DEVICE_PROOF_HEADER, TRUTH_RECORD_KINDS, STORAGE_ERROR_CODES, STORAGE_ERROR_HTTP_STATUS } from '@byok-sdk/core';
2
2
  export { DEVICE_PROOF_HEADER, NONCE_SIGNING_DOMAIN, isTenantId, tenantId } from '@byok-sdk/core';
3
- import { AgentEventOrUnknownSchema, PROTOCOL_VERSION, DAEMON_TO_SERVER_TYPES, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, encodeEnvelope, AgentHomeProjectionCompletionRequestSchema, decodeEnvelope, BYOK_PAIR_PATH, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, BYOK_CAPABILITIES_PATH, BYOK_EVENTS_PATH, BYOK_MESSAGES_PATH, BYOK_AGENT_HOME_PROJECTION_COMPLETION_ROUTE, BYOK_BOARD_PATH, BYOK_BOARD_CLAIM_ROUTE, BYOK_BOARD_UNCLAIM_ROUTE, BYOK_BOARD_STATUS_ROUTE, BYOK_BOARD_STREAM_PATH, BYOK_PRESENCE_PATH, BYOK_ACTIVITY_PATH, BYOK_RECORDS_PATH, BYOK_RECORD_ROUTE, BYOK_SKILL_PACKS_PATH, BYOK_SKILL_PACK_FILE_ROUTE, BYOK_BLOBS_PATH, BYOK_BLOB_FINALIZE_ROUTE, BYOK_BLOB_URL_ROUTE, BYOK_BLOB_CONTENT_ROUTE, createEnvelope, AgentHomeProjectionPayloadSchema, AgentContentReadPayloadSchema, AGENT_EGRESS_POLICY_CAPABILITY, TaskOfferForAgentWithEgressFreshPayloadSchema, TaskOfferForAgentWithEgressPayloadSchema, TaskOfferForAgentPayloadSchema, AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, AGENT_HOME_PROJECTION_CAPABILITY, AGENT_EGRESS_FRESH_SESSION_CAPABILITY, PairRequestSchema, PairResponseSchema, ChallengeRequestSchema, TokenRequestSchema, MessagesSendRequestSchema, PresencePublishRequestSchema, CreateBlobRequestSchema, byokBlobContentPath, AgentEgressAckPayloadSchema, AgentContentReceiptPayloadSchema } from '@byok-sdk/protocol';
3
+ import { AgentEventOrUnknownSchema, PROTOCOL_VERSION, DAEMON_TO_SERVER_TYPES, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, encodeEnvelope, AgentHomeProjectionCompletionRequestSchema, decodeEnvelope, BYOK_PAIR_PATH, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, BYOK_CAPABILITIES_PATH, BYOK_AGENT_MEMORY_PROJECTIONS_PATH, BYOK_EVENTS_PATH, BYOK_MESSAGES_PATH, BYOK_AGENT_HOME_PROJECTION_COMPLETION_ROUTE, BYOK_BOARD_PATH, BYOK_BOARD_CLAIM_ROUTE, BYOK_BOARD_UNCLAIM_ROUTE, BYOK_BOARD_STATUS_ROUTE, BYOK_BOARD_STREAM_PATH, BYOK_PRESENCE_PATH, BYOK_ACTIVITY_PATH, BYOK_RECORDS_PATH, BYOK_RECORD_ROUTE, BYOK_SKILL_PACKS_PATH, BYOK_SKILL_PACK_FILE_ROUTE, BYOK_BLOBS_PATH, BYOK_BLOB_FINALIZE_ROUTE, BYOK_BLOB_URL_ROUTE, BYOK_BLOB_CONTENT_ROUTE, createEnvelope, AgentHomeProjectionPayloadSchema, AgentContentReadPayloadSchema, AGENT_EGRESS_POLICY_CAPABILITY, AGENT_EGRESS_FRESH_SESSION_CAPABILITY, AGENT_MESSAGE_EGRESS_CAPABILITY, TERMINAL_PROJECTION_SELECTION_CAPABILITY, TaskOfferForAgentWithEgressFreshPayloadSchema, AgentMessageServerContextSchema, TaskOfferForAgentWithEgressPayloadSchema, TaskOfferForAgentPayloadSchema, AgentMemoryProjectionMutationSchema, AgentMemoryProjectionReceiptSchema, AGENT_MEMORY_PROJECTION_MAX_ORDERING_VALUE, AgentMemoryProjectionEraseResultSchema, STRICT_AGENT_ONLY_CAPABILITY, AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, AGENT_HOME_PROJECTION_CAPABILITY, PairRequestSchema, PairResponseSchema, ChallengeRequestSchema, TokenRequestSchema, AgentMemoryProjectionCommitRequestSchema, agentMemoryProjectionBase64UrlByteLength, MessagesSendRequestSchema, PresencePublishRequestSchema, CreateBlobRequestSchema, byokBlobContentPath, AgentEgressAckPayloadSchema, AgentContentReceiptPayloadSchema } from '@byok-sdk/protocol';
4
4
  import { z } from 'zod';
5
5
  import { Hono } from 'hono';
6
6
 
@@ -265,7 +265,9 @@ var CLOUD_CAPABILITIES = {
265
265
  * a `SkillPackStore` is refused at construction rather than publishing two
266
266
  * routes it would then 404.
267
267
  */
268
- skillPacks: "skills.pack"
268
+ skillPacks: "skills.pack",
269
+ /** Optional, one-way redacted Agent-memory snapshot mutation route. */
270
+ agentMemoryProjection: "agent.memory.projection"
269
271
  };
270
272
  var CapabilitiesResponseSchema = CapabilityDeclarationSchema;
271
273
  function fullCapabilityDeclaration(version = 1, options = {}) {
@@ -275,6 +277,9 @@ function fullCapabilityDeclaration(version = 1, options = {}) {
275
277
  capabilities: Object.values(CLOUD_CAPABILITIES).filter((capability) => {
276
278
  if (capability === CLOUD_CAPABILITIES.truthRecords) return options.includeTruthRecords === true;
277
279
  if (capability === CLOUD_CAPABILITIES.skillPacks) return options.includeSkillPacks === true;
280
+ if (capability === CLOUD_CAPABILITIES.agentMemoryProjection) {
281
+ return options.includeAgentMemoryProjection === true;
282
+ }
278
283
  return true;
279
284
  })
280
285
  };
@@ -339,7 +344,23 @@ var CLOUD_ERROR_CODES = {
339
344
  /** A task-free completion did not exactly echo its immutable desired projection binding. */
340
345
  agent_home_projection_receipt_mismatch: "agent_home_projection_receipt_mismatch",
341
346
  /** A receipt-store row at the projection namespace violated the frozen projection schema. */
342
- agent_home_projection_receipt_invalid: "agent_home_projection_receipt_invalid"
347
+ agent_home_projection_receipt_invalid: "agent_home_projection_receipt_invalid",
348
+ /** A hosted Agent-memory mutation did not match the durable task/device/AgentRef binding. */
349
+ agent_memory_projection_task_mismatch: "agent_memory_projection_task_mismatch",
350
+ /** The embedder-owned grant/consent authority denied a hosted memory mutation. */
351
+ agent_memory_projection_authorization_denied: "agent_memory_projection_authorization_denied",
352
+ /** A redacted snapshot's decoded bytes did not match its declared hash or byte count. */
353
+ agent_memory_projection_hash_mismatch: "agent_memory_projection_hash_mismatch",
354
+ /** A writer epoch/source sequence already names a different immutable projection mutation. */
355
+ agent_memory_projection_replay_mismatch: "agent_memory_projection_replay_mismatch",
356
+ /** A hosted memory mutation came from an older writer epoch. */
357
+ agent_memory_projection_stale_epoch: "agent_memory_projection_stale_epoch",
358
+ /** A server-side erase fence prevents a deleted writer epoch from re-entering. */
359
+ agent_memory_projection_erased_epoch: "agent_memory_projection_erased_epoch",
360
+ /** A prior erase reached the protocol writer-epoch ceiling and cannot mint a later writer. */
361
+ agent_memory_projection_epoch_exhausted: "agent_memory_projection_epoch_exhausted",
362
+ /** A hosted memory mutation skipped or reset a required source sequence. */
363
+ agent_memory_projection_sequence_gap: "agent_memory_projection_sequence_gap"
343
364
  };
344
365
  var ByokCloudError = class extends Error {
345
366
  code;
@@ -600,6 +621,63 @@ async function readJsonBody(c) {
600
621
  return void 0;
601
622
  }
602
623
  }
624
+ async function readBoundedJsonBody(c, maximum) {
625
+ const declaredLength = c.req.header("content-length");
626
+ if (declaredLength !== void 0) {
627
+ const parsedLength = parseContentLength(declaredLength);
628
+ if (parsedLength !== void 0 && parsedLength > BigInt(maximum)) {
629
+ return { body: void 0, tooLarge: true };
630
+ }
631
+ }
632
+ const stream = c.req.raw.body;
633
+ if (stream === null) return { body: void 0, tooLarge: false };
634
+ const reader = stream.getReader();
635
+ const chunks = [];
636
+ let total = 0;
637
+ try {
638
+ while (true) {
639
+ const { done, value } = await reader.read();
640
+ if (done) break;
641
+ if (value.byteLength > maximum - total) {
642
+ try {
643
+ await reader.cancel();
644
+ } catch {
645
+ }
646
+ return { body: void 0, tooLarge: true };
647
+ }
648
+ if (value.byteLength === 0) continue;
649
+ chunks.push(value);
650
+ total += value.byteLength;
651
+ }
652
+ } catch {
653
+ return { body: void 0, tooLarge: false };
654
+ } finally {
655
+ reader.releaseLock();
656
+ }
657
+ const bytes = new Uint8Array(total);
658
+ let offset = 0;
659
+ for (const chunk of chunks) {
660
+ bytes.set(chunk, offset);
661
+ offset += chunk.byteLength;
662
+ }
663
+ return { body: parseJsonBytes(bytes), tooLarge: false };
664
+ }
665
+ function parseContentLength(value) {
666
+ const normalized = value.trim();
667
+ if (!/^\d+$/u.test(normalized)) return void 0;
668
+ try {
669
+ return BigInt(normalized);
670
+ } catch {
671
+ return void 0;
672
+ }
673
+ }
674
+ function parseJsonBytes(bytes) {
675
+ try {
676
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
677
+ } catch {
678
+ return void 0;
679
+ }
680
+ }
603
681
  async function authenticateDevice(c, deps) {
604
682
  const device = await authenticateBearer(c.req.header("authorization"), deps.bearer);
605
683
  if (device === void 0) return void 0;
@@ -958,6 +1036,45 @@ async function projectTerminalToReview(board, taskId) {
958
1036
  }
959
1037
 
960
1038
  // src/inbound.ts
1039
+ async function handleAgentMessagePublish(stores, deviceId, taskId, payload, consume) {
1040
+ const device = await stores.devices.get(deviceId);
1041
+ const attempt = await stores.tasks.get(taskId);
1042
+ const binding = await stores.receipts.get(`agent-message-offer:${deviceId}:${taskId}`);
1043
+ if (device === void 0 || device.revoked || !hasCapabilities(device.capabilities, [AGENT_MESSAGE_EGRESS_CAPABILITY]) || attempt === void 0 || attempt.deviceId !== deviceId || binding === void 0 || !sameAgentRef(attempt.agentRef, payload.agentRef)) return { outcome: "rejected" };
1044
+ let frozen;
1045
+ try {
1046
+ frozen = JSON.parse(binding.body);
1047
+ } catch {
1048
+ return { outcome: "rejected" };
1049
+ }
1050
+ if (!sameAgentRef(frozen.agentRef, payload.agentRef) || frozen.context === void 0 || frozen.requirement?.contract !== payload.contract || frozen.sessionRef !== void 0 && frozen.sessionRef !== payload.sessionRef || frozen.requirement.contentType !== payload.contentType || typeof frozen.requirement.maxBytes !== "number" || payload.byteCount > frozen.requirement.maxBytes) return { outcome: "rejected" };
1051
+ const taskMessageKey = `agent-message-task:${deviceId}:${taskId}`;
1052
+ const taskMessageBody = JSON.stringify(payload);
1053
+ const lockedTaskMessage = await stores.receipts.record({ key: taskMessageKey, body: taskMessageBody });
1054
+ if (!lockedTaskMessage.created && lockedTaskMessage.receipt.body !== taskMessageBody) return { outcome: "rejected" };
1055
+ const receiptKey2 = `agent-message:${deviceId}:${payload.messageId}`;
1056
+ const previous = await stores.receipts.get(receiptKey2);
1057
+ if (previous !== void 0) {
1058
+ const decoded = JSON.parse(previous.body);
1059
+ if (JSON.stringify(decoded.payload) !== JSON.stringify(payload)) return { outcome: "rejected" };
1060
+ return { outcome: "duplicate", disposition: decoded.disposition };
1061
+ }
1062
+ const decision = consume === void 0 ? { outcome: "held", reasonCode: "consumer_unavailable" } : await consume({ tenant: stores.tenant, deviceId, taskId, context: frozen.context, payload });
1063
+ const disposition = {
1064
+ agentRef: payload.agentRef,
1065
+ sessionRef: payload.sessionRef,
1066
+ contract: payload.contract,
1067
+ messageId: payload.messageId,
1068
+ cursor: payload.cursor,
1069
+ contentHash: payload.contentHash,
1070
+ outcome: decision.outcome,
1071
+ receiptId: crypto.randomUUID(),
1072
+ ...decision.reasonCode === void 0 ? {} : { reasonCode: decision.reasonCode }
1073
+ };
1074
+ const recorded = await stores.receipts.record({ key: receiptKey2, body: JSON.stringify({ payload, disposition }) });
1075
+ if (!recorded.created && recorded.receipt.body !== JSON.stringify({ payload, disposition })) return { outcome: "rejected" };
1076
+ return { outcome: "accepted", disposition };
1077
+ }
961
1078
  function terminalReceiptKey(taskId) {
962
1079
  return `task:${taskId}:terminal`;
963
1080
  }
@@ -1210,13 +1327,23 @@ function messagesHandler(deps) {
1210
1327
  let accepted = 0;
1211
1328
  let rejected = 0;
1212
1329
  for (const envelope of parsed.data.messages) {
1213
- const outcome = await handleInboundEnvelope(
1330
+ const messageResult = envelope.type === "agent.message.publish" ? await handleAgentMessagePublish(
1331
+ stores,
1332
+ device.deviceId,
1333
+ envelope.task_id,
1334
+ envelope.payload,
1335
+ deps.agentMessage?.consume
1336
+ ) : void 0;
1337
+ const outcome = messageResult?.outcome ?? await handleInboundEnvelope(
1214
1338
  stores,
1215
1339
  device.deviceId,
1216
1340
  envelope,
1217
1341
  deps.activityBounds
1218
1342
  );
1219
1343
  if (outcome === "rate_limited") return c.json({ error: "rate limit exceeded" }, 429);
1344
+ if (envelope.type === "agent.message.publish" && messageResult?.disposition !== void 0) {
1345
+ await deps.appendAgentMessageDisposition(stores, device.deviceId, envelope.task_id, messageResult.disposition);
1346
+ }
1220
1347
  if (envelope.type === "agent.egress.reliable" && (outcome === "accepted" || outcome === "duplicate")) {
1221
1348
  const record = await stores.egress.get(device.deviceId, envelope.payload.eventId);
1222
1349
  if (record === void 0) {
@@ -1263,6 +1390,36 @@ function agentHomeProjectionCompletionHandler(deps) {
1263
1390
  }
1264
1391
  };
1265
1392
  }
1393
+ var DEFAULT_MAX_AGENT_MEMORY_PROJECTION_REQUEST_BYTES = 1 * 1024 * 1024;
1394
+ function agentMemoryProjectionHandler(deps) {
1395
+ return async (c) => {
1396
+ const authenticated = await authenticateDevice(c, deps);
1397
+ if (authenticated === void 0) return c.json({ error: "unauthorized" }, 401);
1398
+ const body = await readBoundedJsonBody(c, DEFAULT_MAX_AGENT_MEMORY_PROJECTION_REQUEST_BYTES);
1399
+ if (body.tooLarge) return c.json({ error: "Agent-memory projection request body too large" }, 413);
1400
+ const parsed = AgentMemoryProjectionCommitRequestSchema.safeParse(body.body);
1401
+ if (!parsed.success) return c.json({ error: "invalid Agent-memory projection mutation" }, 422);
1402
+ if (agentMemoryProjectionBase64UrlByteLength(parsed.data.snapshot.redactedBytes) === void 0) {
1403
+ return c.json({ error: "invalid Agent-memory projection mutation" }, 422);
1404
+ }
1405
+ const decoded = base64UrlDecode(parsed.data.snapshot.redactedBytes);
1406
+ if (decoded === void 0 || decoded.byteLength !== parsed.data.snapshot.redactedByteCount) {
1407
+ return c.json({ error: "invalid Agent-memory projection mutation" }, 422);
1408
+ }
1409
+ try {
1410
+ return c.json(
1411
+ await deps.commit(authenticated.stores, authenticated.device.deviceId, parsed.data, decoded),
1412
+ 200
1413
+ );
1414
+ } catch (error) {
1415
+ if (isCloudError(error, "agent_memory_projection_authorization_denied") || isCloudError(error, "agent_memory_projection_task_mismatch") || isCloudError(error, "agent_memory_projection_replay_mismatch") || isCloudError(error, "agent_memory_projection_stale_epoch") || isCloudError(error, "agent_memory_projection_erased_epoch") || isCloudError(error, "agent_memory_projection_epoch_exhausted") || isCloudError(error, "agent_memory_projection_sequence_gap")) return c.json({ error: error.code }, 409);
1416
+ if (isCloudError(error, "agent_memory_projection_hash_mismatch")) {
1417
+ return c.json({ error: error.code }, 422);
1418
+ }
1419
+ throw error;
1420
+ }
1421
+ };
1422
+ }
1266
1423
  var DEFAULT_BOARD_PAGE_LIMIT = 50;
1267
1424
  var DEFAULT_BOARD_STREAM_QUERY_INTERVAL_MS = 5e3;
1268
1425
  var DEFAULT_BOARD_STREAM_HEARTBEAT_INTERVAL_MS = 15e3;
@@ -1809,7 +1966,7 @@ function truthPutHandler(deps) {
1809
1966
  if (authenticated === void 0) return unauthorized2(c);
1810
1967
  const selector = recordSelector(c);
1811
1968
  if (selector === void 0) return c.json({ error: "invalid truth record selector" }, 400);
1812
- const parsedJson = parseJsonBytes(body);
1969
+ const parsedJson = parseJsonBytes2(body);
1813
1970
  const parsed = TruthWriteRequestSchema.safeParse(parsedJson);
1814
1971
  if (!parsed.success) return c.json({ error: "invalid truth write request" }, 400);
1815
1972
  const writes = prepareWrites(selector.kind, selector.recordKey, parsed.data);
@@ -1944,7 +2101,7 @@ async function readBoundedBody(c, maximum) {
1944
2101
  return void 0;
1945
2102
  }
1946
2103
  }
1947
- function parseJsonBytes(bytes) {
2104
+ function parseJsonBytes2(bytes) {
1948
2105
  try {
1949
2106
  return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
1950
2107
  } catch {
@@ -2188,7 +2345,9 @@ function createByokCloud(options) {
2188
2345
  options.blobContentProxy,
2189
2346
  options.truthCommitter,
2190
2347
  options.truthObjectDownloads,
2191
- options.skillPacks
2348
+ options.skillPacks,
2349
+ options.agentMemoryProjectionAuthorizer,
2350
+ options.agentMemoryProjectionStore
2192
2351
  );
2193
2352
  const root = { core: options.core, cloud: options.cloud };
2194
2353
  const auth = createAuthPlane({
@@ -2216,6 +2375,15 @@ function createByokCloud(options) {
2216
2375
  { method: "GET", path: BYOK_CAPABILITIES_PATH, class: "public" },
2217
2376
  capabilitiesHandler({ declaration })
2218
2377
  );
2378
+ if (declares(declaration, CLOUD_CAPABILITIES.agentMemoryProjection)) {
2379
+ registry.register(
2380
+ { method: "POST", path: BYOK_AGENT_MEMORY_PROJECTIONS_PATH, class: "device" },
2381
+ agentMemoryProjectionHandler({
2382
+ ...deviceRouteDeps,
2383
+ commit: (stores, deviceId, mutation, redactedBytes) => commitAgentMemoryProjectionFromStores(stores, deviceId, mutation, redactedBytes)
2384
+ })
2385
+ );
2386
+ }
2219
2387
  if (declares(declaration, CLOUD_CAPABILITIES.eventsLongPoll)) {
2220
2388
  registry.register(
2221
2389
  { method: "GET", path: BYOK_EVENTS_PATH, class: "device" },
@@ -2234,7 +2402,9 @@ function createByokCloud(options) {
2234
2402
  ...deviceRouteDeps,
2235
2403
  activityBounds,
2236
2404
  appendReliableEgressAck: enqueueReliableEgressAck,
2237
- appendContentReceiptAck: enqueueContentReceiptAck
2405
+ appendContentReceiptAck: enqueueContentReceiptAck,
2406
+ agentMessage: options.agentMessage,
2407
+ appendAgentMessageDisposition: enqueueAgentMessageDisposition
2238
2408
  })
2239
2409
  );
2240
2410
  }
@@ -2360,7 +2530,7 @@ function createByokCloud(options) {
2360
2530
  function controlPlane(tenant) {
2361
2531
  return { kind: "control-plane", tenantId: tenant, operatorId };
2362
2532
  }
2363
- async function enqueueTaskEnvelope(tenant, deviceId, requestedTaskId, agentRef, buildEnvelope) {
2533
+ async function enqueueTaskEnvelope(tenant, deviceId, requestedTaskId, agentRef, buildEnvelope, beforeMailbox) {
2364
2534
  const stores = tenantStoresFor(controlPlane(tenant), root);
2365
2535
  const taskId = requestedTaskId ?? `task_${options.crypto.randomUuid()}`;
2366
2536
  const messageId = options.crypto.randomUuid();
@@ -2380,6 +2550,7 @@ function createByokCloud(options) {
2380
2550
  }
2381
2551
  let message;
2382
2552
  try {
2553
+ await beforeMailbox?.(stores, taskId);
2383
2554
  message = await stores.mailbox.append({
2384
2555
  deviceId,
2385
2556
  messageId,
@@ -2435,6 +2606,15 @@ function createByokCloud(options) {
2435
2606
  );
2436
2607
  }
2437
2608
  }
2609
+ async function assertLegacyAdmission(tenant, deviceId) {
2610
+ const device = await options.cloud.devices.get(tenant, deviceId);
2611
+ if (device?.capabilities?.includes(STRICT_AGENT_ONLY_CAPABILITY) === true) {
2612
+ throw new ByokCloudError(
2613
+ "agent_capability_missing",
2614
+ `Device ${deviceId} advertises strict-agent-only; refusing legacy offer before mailbox append.`
2615
+ );
2616
+ }
2617
+ }
2438
2618
  function contentReadCapability2(surface) {
2439
2619
  switch (surface) {
2440
2620
  case "workspace":
@@ -2497,6 +2677,54 @@ function createByokCloud(options) {
2497
2677
  receipt
2498
2678
  );
2499
2679
  }
2680
+ async function commitAgentMemoryProjectionFromStores(stores, deviceId, mutationInput, redactedBytes) {
2681
+ const mutation = AgentMemoryProjectionCommitRequestSchema.parse(mutationInput);
2682
+ const attempt = await stores.tasks.get(mutation.taskId);
2683
+ if (attempt === void 0 || attempt.deviceId !== deviceId || !sameAgentRef2(mutation.agentRef, attempt.agentRef)) {
2684
+ throw new ByokCloudError(
2685
+ "agent_memory_projection_task_mismatch",
2686
+ "The Agent-memory projection does not match an exact task/device/AgentRef binding."
2687
+ );
2688
+ }
2689
+ const authorizer = options.agentMemoryProjectionAuthorizer;
2690
+ const store = options.agentMemoryProjectionStore;
2691
+ if (authorizer === void 0 || store === void 0) {
2692
+ throw new ByokCloudError(
2693
+ "agent_capability_missing",
2694
+ "Hosted Agent-memory projection requires both an authorizer and a projection store."
2695
+ );
2696
+ }
2697
+ const authorization = await authorizer.authorize({
2698
+ tenantId: stores.tenant,
2699
+ deviceId,
2700
+ taskId: mutation.taskId,
2701
+ agentRef: mutation.agentRef,
2702
+ sessionRef: mutation.sessionRef,
2703
+ runtimeId: mutation.runtimeId,
2704
+ grantRef: mutation.grantRef,
2705
+ writerEpoch: mutation.writerEpoch,
2706
+ policyRevision: mutation.policyRevision
2707
+ });
2708
+ if (authorization.outcome !== "authorized") {
2709
+ throw new ByokCloudError(
2710
+ "agent_memory_projection_authorization_denied",
2711
+ `The Agent-memory projection grant was denied: ${authorization.reasonCode}`
2712
+ );
2713
+ }
2714
+ return store.commit({ tenantId: stores.tenant, deviceId, mutation, redactedBytes });
2715
+ }
2716
+ async function eraseAgentMemoryProjection(tenant, agentId) {
2717
+ const authorizer = options.agentMemoryProjectionAuthorizer;
2718
+ const store = options.agentMemoryProjectionStore;
2719
+ if (authorizer === void 0 || store === void 0) {
2720
+ throw new ByokCloudError(
2721
+ "agent_capability_missing",
2722
+ "Hosted Agent-memory projection is not configured for this deployment."
2723
+ );
2724
+ }
2725
+ await authorizer.revoke({ tenantId: tenant, agentId });
2726
+ return store.erase({ tenantId: tenant, agentId });
2727
+ }
2500
2728
  async function enqueueReliableEgressAck(stores, record) {
2501
2729
  const payload = AgentEgressAckPayloadSchema.parse({
2502
2730
  agentRef: record.payload.agentRef,
@@ -2564,6 +2792,25 @@ function createByokCloud(options) {
2564
2792
  );
2565
2793
  }
2566
2794
  }
2795
+ async function enqueueAgentMessageDisposition(stores, deviceId, taskId, payload) {
2796
+ const message = await stores.mailbox.append({
2797
+ deviceId,
2798
+ messageId: `agent-message-disposition:${payload.receiptId}`,
2799
+ materialize: async (seq) => {
2800
+ const body = encodeEnvelope(createEnvelope("agent.message.disposition", payload, {
2801
+ id: payload.receiptId,
2802
+ taskId,
2803
+ seq
2804
+ }));
2805
+ const bytes = new TextEncoder().encode(body);
2806
+ return { body, bodyHash: contentHash(await options.crypto.sha256(bytes)), byteSize: BigInt(bytes.length) };
2807
+ }
2808
+ });
2809
+ const decoded = decodeEnvelope(message.body);
2810
+ if (decoded.type !== "agent.message.disposition" || decoded.seq !== message.seq) {
2811
+ throw new ByokCloudError("mailbox_receipt_mismatch", "Agent message disposition mailbox readback mismatched.");
2812
+ }
2813
+ }
2567
2814
  return {
2568
2815
  fetch: registry.fetch,
2569
2816
  routes: registry.routes,
@@ -2573,6 +2820,7 @@ function createByokCloud(options) {
2573
2820
  return auth.createPairingCode(tenant, input);
2574
2821
  },
2575
2822
  async enqueueOffer(tenant, deviceId, input) {
2823
+ await assertLegacyAdmission(tenant, deviceId);
2576
2824
  return enqueueTaskEnvelope(
2577
2825
  tenant,
2578
2826
  deviceId,
@@ -2582,6 +2830,7 @@ function createByokCloud(options) {
2582
2830
  );
2583
2831
  },
2584
2832
  async enqueueToolsetOffer(tenant, deviceId, input) {
2833
+ await assertLegacyAdmission(tenant, deviceId);
2585
2834
  return enqueueTaskEnvelope(
2586
2835
  tenant,
2587
2836
  deviceId,
@@ -2591,7 +2840,10 @@ function createByokCloud(options) {
2591
2840
  );
2592
2841
  },
2593
2842
  async enqueueAgentOffer(tenant, deviceId, input) {
2594
- await assertAgentCapabilities(tenant, deviceId, [AGENT_HOME_CONTRACT_CAPABILITY]);
2843
+ await assertAgentCapabilities(tenant, deviceId, [
2844
+ AGENT_HOME_CONTRACT_CAPABILITY,
2845
+ ...input.payload.terminalProjection === void 0 ? [] : [TERMINAL_PROJECTION_SELECTION_CAPABILITY]
2846
+ ]);
2595
2847
  const payload = TaskOfferForAgentPayloadSchema.parse(input.payload);
2596
2848
  return enqueueTaskEnvelope(
2597
2849
  tenant,
@@ -2605,32 +2857,60 @@ function createByokCloud(options) {
2605
2857
  await assertAgentCapabilities(tenant, deviceId, [
2606
2858
  AGENT_HOME_CONTRACT_CAPABILITY,
2607
2859
  AGENT_EGRESS_POLICY_CAPABILITY,
2608
- AGENT_EGRESS_RELIABLE_ACK_CAPABILITY
2860
+ AGENT_EGRESS_RELIABLE_ACK_CAPABILITY,
2861
+ ...input.payload.messageEgress === void 0 ? [] : [AGENT_MESSAGE_EGRESS_CAPABILITY],
2862
+ ...input.payload.terminalProjection === void 0 ? [] : [TERMINAL_PROJECTION_SELECTION_CAPABILITY]
2609
2863
  ]);
2610
2864
  const payload = TaskOfferForAgentWithEgressPayloadSchema.parse(input.payload);
2611
- return enqueueTaskEnvelope(
2865
+ if (payload.messageEgress === void 0 && input.agentMessageContext !== void 0) {
2866
+ throw new Error("agentMessageContext requires messageEgress");
2867
+ }
2868
+ const messageContext = payload.messageEgress === void 0 ? void 0 : AgentMessageServerContextSchema.parse(input.agentMessageContext);
2869
+ const enqueued = await enqueueTaskEnvelope(
2612
2870
  tenant,
2613
2871
  deviceId,
2614
2872
  input.taskId,
2615
2873
  payload.agentRef,
2616
- (taskId, seq, messageId) => createEnvelope("task.offer_for_agent_with_egress", payload, { id: messageId, taskId, seq })
2874
+ (taskId, seq, messageId) => createEnvelope("task.offer_for_agent_with_egress", payload, { id: messageId, taskId, seq }),
2875
+ payload.messageEgress === void 0 ? void 0 : async (stores, taskId) => {
2876
+ const body = JSON.stringify({ agentRef: payload.agentRef, sessionRef: payload.sessionRef, requirement: payload.messageEgress, context: messageContext });
2877
+ const recorded = await stores.receipts.record({ key: `agent-message-offer:${deviceId}:${taskId}`, body });
2878
+ if (!recorded.created && recorded.receipt.body !== body) {
2879
+ throw new ByokCloudError("agent_content_request_mismatch", `Task ${taskId} already has a different Agent message context.`);
2880
+ }
2881
+ }
2617
2882
  );
2883
+ return enqueued;
2618
2884
  },
2619
2885
  async enqueueFreshAgentEgressOffer(tenant, deviceId, input) {
2620
2886
  await assertAgentCapabilities(tenant, deviceId, [
2621
2887
  AGENT_HOME_CONTRACT_CAPABILITY,
2622
2888
  AGENT_EGRESS_POLICY_CAPABILITY,
2623
2889
  AGENT_EGRESS_RELIABLE_ACK_CAPABILITY,
2624
- AGENT_EGRESS_FRESH_SESSION_CAPABILITY
2890
+ AGENT_EGRESS_FRESH_SESSION_CAPABILITY,
2891
+ ...input.payload.messageEgress === void 0 ? [] : [AGENT_MESSAGE_EGRESS_CAPABILITY],
2892
+ ...input.payload.terminalProjection === void 0 ? [] : [TERMINAL_PROJECTION_SELECTION_CAPABILITY]
2625
2893
  ]);
2626
2894
  const payload = TaskOfferForAgentWithEgressFreshPayloadSchema.parse(input.payload);
2627
- return enqueueTaskEnvelope(
2895
+ if (payload.messageEgress === void 0 && input.agentMessageContext !== void 0) {
2896
+ throw new Error("agentMessageContext requires messageEgress");
2897
+ }
2898
+ const messageContext = payload.messageEgress === void 0 ? void 0 : AgentMessageServerContextSchema.parse(input.agentMessageContext);
2899
+ const enqueued = await enqueueTaskEnvelope(
2628
2900
  tenant,
2629
2901
  deviceId,
2630
2902
  input.taskId,
2631
2903
  payload.agentRef,
2632
- (taskId, seq, messageId) => createEnvelope("task.offer_for_agent_with_egress_fresh", payload, { id: messageId, taskId, seq })
2904
+ (taskId, seq, messageId) => createEnvelope("task.offer_for_agent_with_egress_fresh", payload, { id: messageId, taskId, seq }),
2905
+ payload.messageEgress === void 0 ? void 0 : async (stores, taskId) => {
2906
+ const body = JSON.stringify({ agentRef: payload.agentRef, requirement: payload.messageEgress, context: messageContext });
2907
+ const recorded = await stores.receipts.record({ key: `agent-message-offer:${deviceId}:${taskId}`, body });
2908
+ if (!recorded.created && recorded.receipt.body !== body) {
2909
+ throw new ByokCloudError("agent_content_request_mismatch", `Task ${taskId} already has a different Agent message context.`);
2910
+ }
2911
+ }
2633
2912
  );
2913
+ return enqueued;
2634
2914
  },
2635
2915
  async enqueueAgentContentRead(tenant, deviceId, input) {
2636
2916
  const payload = AgentContentReadPayloadSchema.parse(input.payload);
@@ -2711,6 +2991,7 @@ function createByokCloud(options) {
2711
2991
  },
2712
2992
  getAgentHomeProjectionStatus,
2713
2993
  completeAgentHomeProjection,
2994
+ eraseAgentMemoryProjection,
2714
2995
  async cancelTask(tenant, taskId, reason) {
2715
2996
  const stores = tenantStoresFor(controlPlane(tenant), root);
2716
2997
  const proposedMessageId = options.crypto.randomUuid();
@@ -2811,7 +3092,7 @@ function createByokCloud(options) {
2811
3092
  }
2812
3093
  };
2813
3094
  }
2814
- function assertNoOverDeclaration(declaration, contentProxy, truthCommitter, truthObjectDownloads, skillPacks) {
3095
+ function assertNoOverDeclaration(declaration, contentProxy, truthCommitter, truthObjectDownloads, skillPacks, agentMemoryProjectionAuthorizer, agentMemoryProjectionStore) {
2815
3096
  if (declares(declaration, CLOUD_CAPABILITIES.boardSse) && !declares(declaration, CLOUD_CAPABILITIES.boardCoordination)) {
2816
3097
  throw new ByokCloudError(
2817
3098
  "capability_over_declared",
@@ -2842,6 +3123,12 @@ function assertNoOverDeclaration(declaration, contentProxy, truthCommitter, trut
2842
3123
  `This deployment declares ${CLOUD_CAPABILITIES.skillPacks} but was given no SkillPackStore, so both /byok/skill-packs routes would be published and unserved.`
2843
3124
  );
2844
3125
  }
3126
+ if (declares(declaration, CLOUD_CAPABILITIES.agentMemoryProjection) && (agentMemoryProjectionAuthorizer === void 0 || agentMemoryProjectionStore === void 0)) {
3127
+ throw new ByokCloudError(
3128
+ "capability_over_declared",
3129
+ `This deployment declares ${CLOUD_CAPABILITIES.agentMemoryProjection} but was given no complete AgentMemoryProjectionAuthorizer/AgentMemoryProjectionStore pair.`
3130
+ );
3131
+ }
2845
3132
  }
2846
3133
  function parseDeclaration(declaration) {
2847
3134
  try {
@@ -3595,10 +3882,15 @@ function createInMemoryByokCloud(options = {}) {
3595
3882
  crypto: crypto2,
3596
3883
  tokenSigner,
3597
3884
  clock,
3598
- capabilities: options.capabilities ?? fullCapabilityDeclaration(),
3885
+ capabilities: options.capabilities ?? fullCapabilityDeclaration(void 0, {
3886
+ includeAgentMemoryProjection: options.agentMemoryProjectionAuthorizer !== void 0 && options.agentMemoryProjectionStore !== void 0
3887
+ }),
3599
3888
  ...options.truthCommitter === void 0 ? {} : { truthCommitter: options.truthCommitter },
3600
3889
  ...options.truthObjectDownloads === void 0 ? {} : { truthObjectDownloads: options.truthObjectDownloads },
3601
3890
  ...options.operatorId !== void 0 ? { operatorId: options.operatorId } : {},
3891
+ ...options.agentMessage === void 0 ? {} : { agentMessage: options.agentMessage },
3892
+ ...options.agentMemoryProjectionAuthorizer === void 0 ? {} : { agentMemoryProjectionAuthorizer: options.agentMemoryProjectionAuthorizer },
3893
+ ...options.agentMemoryProjectionStore === void 0 ? {} : { agentMemoryProjectionStore: options.agentMemoryProjectionStore },
3602
3894
  ...options.maxBlobSizeBytes !== void 0 ? { maxBlobSizeBytes: options.maxBlobSizeBytes } : {},
3603
3895
  ...options.longPollHoldMs !== void 0 ? { longPollHoldMs: options.longPollHoldMs } : {},
3604
3896
  ...options.longPollIntervalMs !== void 0 ? { longPollIntervalMs: options.longPollIntervalMs } : {},
@@ -3623,6 +3915,187 @@ function createInMemoryByokCloud(options = {}) {
3623
3915
  });
3624
3916
  return { cloud, core, stores, blobContentProxy, clock, crypto: crypto2 };
3625
3917
  }
3918
+ function agentKey(tenantId4, agentId) {
3919
+ return `${tenantId4}\0${agentId}`;
3920
+ }
3921
+ function permitKey(input) {
3922
+ return JSON.stringify([
3923
+ input.tenantId,
3924
+ input.deviceId,
3925
+ input.taskId,
3926
+ input.agentRef.agentId,
3927
+ input.agentRef.profileRevision,
3928
+ input.sessionRef,
3929
+ input.runtimeId,
3930
+ input.grantRef,
3931
+ input.writerEpoch,
3932
+ input.policyRevision
3933
+ ]);
3934
+ }
3935
+ function receiptKey(input) {
3936
+ const { mutation } = input;
3937
+ return `${agentKey(input.tenantId, mutation.agentRef.agentId)}\0${mutation.writerEpoch}\0${mutation.sourceSeq}`;
3938
+ }
3939
+ function sameMutationReceipt(receipt, input) {
3940
+ const { mutation } = input;
3941
+ return receipt.tenantId === input.tenantId && receipt.deviceId === input.deviceId && receipt.taskId === mutation.taskId && receipt.agentRef.agentId === mutation.agentRef.agentId && receipt.agentRef.profileRevision === mutation.agentRef.profileRevision && receipt.sessionRef === mutation.sessionRef && receipt.runtimeId === mutation.runtimeId && receipt.grantRef === mutation.grantRef && receipt.writerEpoch === mutation.writerEpoch && receipt.sourceSeq === mutation.sourceSeq && receipt.mutationId === mutation.mutationId && receipt.policyRevision === mutation.policyRevision && receipt.redactedHash === mutation.snapshot.redactedHash && receipt.redactedByteCount === mutation.snapshot.redactedByteCount;
3942
+ }
3943
+ var InMemoryAgentMemoryProjectionStore = class {
3944
+ #clock;
3945
+ #crypto;
3946
+ #heads = /* @__PURE__ */ new Map();
3947
+ #snapshots = /* @__PURE__ */ new Map();
3948
+ #receipts = /* @__PURE__ */ new Map();
3949
+ /** Minimum legal future epoch after server-side erasure; contains no body. */
3950
+ #eraseFences = /* @__PURE__ */ new Map();
3951
+ #mutationTails = /* @__PURE__ */ new Map();
3952
+ constructor(clock, crypto2) {
3953
+ this.#clock = clock;
3954
+ this.#crypto = crypto2;
3955
+ }
3956
+ async commit(input) {
3957
+ const mutation = AgentMemoryProjectionMutationSchema.parse(input.mutation);
3958
+ if (input.redactedBytes.byteLength !== mutation.snapshot.redactedByteCount) {
3959
+ throw new ByokCloudError(
3960
+ "agent_memory_projection_hash_mismatch",
3961
+ "Decoded redacted snapshot bytes do not match redactedByteCount."
3962
+ );
3963
+ }
3964
+ const hash = await this.#crypto.sha256(input.redactedBytes);
3965
+ if (hash !== mutation.snapshot.redactedHash) {
3966
+ throw new ByokCloudError(
3967
+ "agent_memory_projection_hash_mismatch",
3968
+ "Decoded redacted snapshot bytes do not match redactedHash."
3969
+ );
3970
+ }
3971
+ const exactInput = { ...input, mutation };
3972
+ const key = agentKey(input.tenantId, mutation.agentRef.agentId);
3973
+ return this.#mutate(key, () => {
3974
+ const prior = this.#receipts.get(receiptKey(exactInput));
3975
+ if (prior !== void 0) {
3976
+ if (!sameMutationReceipt(prior, exactInput)) {
3977
+ throw new ByokCloudError(
3978
+ "agent_memory_projection_replay_mismatch",
3979
+ "A memory projection epoch and source sequence already names a different immutable mutation."
3980
+ );
3981
+ }
3982
+ return AgentMemoryProjectionReceiptSchema.parse({ ...prior, outcome: "idempotent" });
3983
+ }
3984
+ const fence = this.#eraseFences.get(key);
3985
+ if (fence !== void 0 && mutation.writerEpoch < fence) {
3986
+ throw new ByokCloudError("agent_memory_projection_erased_epoch", "The memory projection writerEpoch was erased and cannot be replayed.");
3987
+ }
3988
+ const head = this.#heads.get(key);
3989
+ if (head === void 0) {
3990
+ if (mutation.sourceSeq !== 1) {
3991
+ throw new ByokCloudError(
3992
+ "agent_memory_projection_sequence_gap",
3993
+ "The first memory projection mutation must use sourceSeq 1."
3994
+ );
3995
+ }
3996
+ } else if (mutation.writerEpoch < head.writerEpoch) {
3997
+ throw new ByokCloudError("agent_memory_projection_stale_epoch", "The memory projection writerEpoch is stale.");
3998
+ } else if (mutation.writerEpoch > head.writerEpoch) {
3999
+ if (mutation.sourceSeq !== 1) {
4000
+ throw new ByokCloudError(
4001
+ "agent_memory_projection_sequence_gap",
4002
+ "A new memory projection writerEpoch must start at sourceSeq 1."
4003
+ );
4004
+ }
4005
+ } else if (mutation.sourceSeq !== head.sourceSeq + 1) {
4006
+ throw new ByokCloudError(
4007
+ "agent_memory_projection_sequence_gap",
4008
+ "A memory projection mutation must advance sourceSeq exactly by one."
4009
+ );
4010
+ }
4011
+ const recordedAt = this.#clock.now().toISOString();
4012
+ const metering = {
4013
+ meteringReceiptId: this.#crypto.randomUuid(),
4014
+ acceptedRedactedBytes: mutation.snapshot.redactedByteCount,
4015
+ recordedAt
4016
+ };
4017
+ const receipt = AgentMemoryProjectionReceiptSchema.parse({
4018
+ outcome: "accepted",
4019
+ tenantId: input.tenantId,
4020
+ deviceId: input.deviceId,
4021
+ taskId: mutation.taskId,
4022
+ agentRef: mutation.agentRef,
4023
+ sessionRef: mutation.sessionRef,
4024
+ runtimeId: mutation.runtimeId,
4025
+ grantRef: mutation.grantRef,
4026
+ writerEpoch: mutation.writerEpoch,
4027
+ sourceSeq: mutation.sourceSeq,
4028
+ mutationId: mutation.mutationId,
4029
+ policyRevision: mutation.policyRevision,
4030
+ redactedHash: mutation.snapshot.redactedHash,
4031
+ redactedByteCount: mutation.snapshot.redactedByteCount,
4032
+ metering
4033
+ });
4034
+ this.#snapshots.set(key, {
4035
+ redactedBytes: input.redactedBytes.slice(),
4036
+ redactedHash: mutation.snapshot.redactedHash,
4037
+ redactedByteCount: mutation.snapshot.redactedByteCount
4038
+ });
4039
+ this.#heads.set(key, { writerEpoch: mutation.writerEpoch, sourceSeq: mutation.sourceSeq });
4040
+ this.#receipts.set(receiptKey(exactInput), receipt);
4041
+ return receipt;
4042
+ });
4043
+ }
4044
+ async erase(input) {
4045
+ const key = agentKey(input.tenantId, input.agentId);
4046
+ return this.#mutate(key, () => {
4047
+ const priorHeadEpoch = this.#heads.get(key)?.writerEpoch ?? 0;
4048
+ const nextWriterEpoch = Math.max(this.#eraseFences.get(key) ?? 1, priorHeadEpoch + 1);
4049
+ if (nextWriterEpoch > AGENT_MEMORY_PROJECTION_MAX_ORDERING_VALUE) {
4050
+ throw new ByokCloudError("agent_memory_projection_epoch_exhausted", "The memory projection writerEpoch cannot advance after erase.");
4051
+ }
4052
+ this.#heads.delete(key);
4053
+ this.#snapshots.delete(key);
4054
+ const prefix = `${key}\0`;
4055
+ for (const receiptKeyValue of this.#receipts.keys()) {
4056
+ if (receiptKeyValue.startsWith(prefix)) this.#receipts.delete(receiptKeyValue);
4057
+ }
4058
+ this.#eraseFences.set(key, nextWriterEpoch);
4059
+ return AgentMemoryProjectionEraseResultSchema.parse({ nextWriterEpoch });
4060
+ });
4061
+ }
4062
+ async #mutate(key, operation) {
4063
+ const previous = this.#mutationTails.get(key) ?? Promise.resolve();
4064
+ const result = previous.then(operation);
4065
+ const tail = result.then(() => void 0, () => void 0);
4066
+ this.#mutationTails.set(key, tail);
4067
+ try {
4068
+ return await result;
4069
+ } finally {
4070
+ if (this.#mutationTails.get(key) === tail) this.#mutationTails.delete(key);
4071
+ }
4072
+ }
4073
+ };
4074
+ var InMemoryAgentMemoryProjectionAuthorizer = class {
4075
+ #grants = /* @__PURE__ */ new Map();
4076
+ /** Highest host-issued epoch observed for each tenant/Agent authority. */
4077
+ #highestEpochs = /* @__PURE__ */ new Map();
4078
+ grant(input) {
4079
+ const key = agentKey(input.tenantId, input.agentRef.agentId);
4080
+ const highestEpoch = this.#highestEpochs.get(key);
4081
+ if (highestEpoch !== void 0 && input.writerEpoch < highestEpoch) return;
4082
+ if (highestEpoch === void 0 || input.writerEpoch > highestEpoch) {
4083
+ for (const [grantKey, grant] of this.#grants) {
4084
+ if (grant.tenantId === input.tenantId && grant.agentRef.agentId === input.agentRef.agentId && grant.writerEpoch < input.writerEpoch) this.#grants.delete(grantKey);
4085
+ }
4086
+ this.#highestEpochs.set(key, input.writerEpoch);
4087
+ }
4088
+ this.#grants.set(permitKey(input), { ...input, agentRef: { ...input.agentRef } });
4089
+ }
4090
+ async authorize(input) {
4091
+ return this.#grants.has(permitKey(input)) ? { outcome: "authorized" } : { outcome: "denied", reasonCode: "grant_not_authorized" };
4092
+ }
4093
+ async revoke(input) {
4094
+ for (const [key, grant] of this.#grants) {
4095
+ if (grant.tenantId === input.tenantId && grant.agentRef.agentId === input.agentId) this.#grants.delete(key);
4096
+ }
4097
+ }
4098
+ };
3626
4099
  function authenticateHostedDeviceAssertion(input, deps) {
3627
4100
  return authenticateDeviceAssertion(input, {
3628
4101
  verifier: {
@@ -3841,6 +4314,6 @@ var CLOUD_PORT_INTERFACES = {
3841
4314
  rateLimiter: "InboundRateLimiter"
3842
4315
  };
3843
4316
 
3844
- export { ACCESS_TOKEN_TTL_SECONDS, AGENT_HOME_CONTRACT_CAPABILITY, APPROVAL_SUMMARY_MAX_BYTES, ActivityAppendRequestSchema, AllowAllRateLimiter, ApprovalObservationSchema, ApprovalTimelineEventSchema, BLOB_READ_ERROR_CODES, BLOB_URL_TTL_MS, BoardFeedClient, BoardFeedRetryableError, BoardFeedStoppedError, ByokCloudError, CLOUD_CAPABILITIES, CLOUD_ERROR_CODES, CLOUD_PORT_INTERFACES, CLOUD_PORT_METHODS, CLOUD_STORE_NAMES, CapabilitiesResponseSchema, CloudRouteRegistry, DEDUP_RING_CAPACITY, DEFAULT_ACTIVITY_BOUNDS, DEFAULT_ACTIVITY_CAPACITY, DEFAULT_ACTIVITY_MAX_BYTES, DEFAULT_ACTIVITY_MAX_EVENTS, DEFAULT_ACTIVITY_TTL_MS, DEFAULT_APPROVAL_TIMELINE_CAPACITY, DEFAULT_APPROVAL_TIMELINE_TTL_MS, DEFAULT_BOARD_CHANNEL_MAX_BYTES, DEFAULT_BOARD_PAGE_LIMIT, DEFAULT_BOARD_STREAM_HEARTBEAT_INTERVAL_MS, DEFAULT_BOARD_STREAM_QUERY_INTERVAL_MS, DEFAULT_BOARD_STREAM_RECONCILIATION_INTERVAL_MS, DEFAULT_BOARD_TITLE_MAX_BYTES, DEFAULT_DEVICE_PROOF_CLOCK_SKEW_MS, DEFAULT_DEVICE_PROOF_MAX_LIFETIME_MS, DEFAULT_EVENTS_PAGE_LIMIT, DEFAULT_LONG_POLL_HOLD_MS, DEFAULT_LONG_POLL_INTERVAL_MS, DEFAULT_MAX_BLOB_SIZE_BYTES, DEFAULT_MAX_TRUTH_REQUEST_BYTES, DEFAULT_PRESENCE_DETAIL_MAX_BYTES, DEFAULT_PRESENCE_MINIMUM_INTERVAL_MS, DEFAULT_PRESENCE_TTL_MS, DEFAULT_SKILL_PACK_PAGE_LIMIT, DEVICE_IDENTITY_PROOF_KEY_EPOCH, DEVICE_IDENTITY_PROOF_KEY_ID, InMemoryActivityStore, InMemoryAgentEgressStore, InMemoryBlobContentProxy, InMemoryCloudBlobStore, InMemoryDeviceDirectory, InMemoryInboundDedupStore, InMemoryNonceStore, InMemoryPairingCodeStore, InMemoryProofRequestReceiptStore, InMemoryRequestReceiptStore, InMemoryTaskAttemptStore, InMemoryTaskCancellationStore, MAX_DEVICE_PROOF_CLOCK_SKEW_MS, MAX_DEVICE_PROOF_HEADER_BYTES, MAX_DEVICE_PROOF_MAX_LIFETIME_MS, NONCE_TTL_MS, PAIRING_CODE_TTL_MS, ROUTE_CLASSES, ROUTE_METHODS, TASK_ATTEMPT_STATUSES, TRUTH_BATCH_MAX_RECORDS, TRUTH_INLINE_CONTENT_TYPE, TRUTH_LABEL_MAX_LENGTH, TRUTH_MANIFEST_MAX_LIMIT, TRUTH_RECORD_CAPABILITY, TRUTH_RECORD_KEY_MAX_LENGTH, TRUTH_REQUEST_ID_MAX_LENGTH, TimelineEventSchema, TruthBodyInputSchema, TruthCommitError, TruthCommitResponseSchema, TruthRecordKeySchema, TruthRecordMetadataSchema, TruthWriteRequestSchema, activityCursor, agentHomeProjectionCompletionKey, agentHomeProjectionRequestKey, approvalTimelineCursor, authenticateBearer, authenticateDeviceProof, authenticateHostedDeviceAssertion, createAuthPlane, createByokCloud, createHmacTokenSigner, createInMemoryBlobs, createInMemoryByokCloud, createInMemoryCloudStores, createWebCrypto, declares, extractBearerToken, fullCapabilityDeclaration, handleInboundEnvelope, isCloudError, isTruthCommitError, parseApprovalObservations, parseTimelineEvents, projectTerminalResult, projectTimelineEvents, readAgentHomeProjectionStatus, recordAgentHomeProjectionCompletion, routeKey, tenantStoresFor, terminalReceiptKey, truthManifestMetadata, truthRecordMetadata, validateActivityAppend, validateApprovalTimelineAppend, verifyNonceSignature };
4317
+ export { ACCESS_TOKEN_TTL_SECONDS, AGENT_HOME_CONTRACT_CAPABILITY, APPROVAL_SUMMARY_MAX_BYTES, ActivityAppendRequestSchema, AllowAllRateLimiter, ApprovalObservationSchema, ApprovalTimelineEventSchema, BLOB_READ_ERROR_CODES, BLOB_URL_TTL_MS, BoardFeedClient, BoardFeedRetryableError, BoardFeedStoppedError, ByokCloudError, CLOUD_CAPABILITIES, CLOUD_ERROR_CODES, CLOUD_PORT_INTERFACES, CLOUD_PORT_METHODS, CLOUD_STORE_NAMES, CapabilitiesResponseSchema, CloudRouteRegistry, DEDUP_RING_CAPACITY, DEFAULT_ACTIVITY_BOUNDS, DEFAULT_ACTIVITY_CAPACITY, DEFAULT_ACTIVITY_MAX_BYTES, DEFAULT_ACTIVITY_MAX_EVENTS, DEFAULT_ACTIVITY_TTL_MS, DEFAULT_APPROVAL_TIMELINE_CAPACITY, DEFAULT_APPROVAL_TIMELINE_TTL_MS, DEFAULT_BOARD_CHANNEL_MAX_BYTES, DEFAULT_BOARD_PAGE_LIMIT, DEFAULT_BOARD_STREAM_HEARTBEAT_INTERVAL_MS, DEFAULT_BOARD_STREAM_QUERY_INTERVAL_MS, DEFAULT_BOARD_STREAM_RECONCILIATION_INTERVAL_MS, DEFAULT_BOARD_TITLE_MAX_BYTES, DEFAULT_DEVICE_PROOF_CLOCK_SKEW_MS, DEFAULT_DEVICE_PROOF_MAX_LIFETIME_MS, DEFAULT_EVENTS_PAGE_LIMIT, DEFAULT_LONG_POLL_HOLD_MS, DEFAULT_LONG_POLL_INTERVAL_MS, DEFAULT_MAX_BLOB_SIZE_BYTES, DEFAULT_MAX_TRUTH_REQUEST_BYTES, DEFAULT_PRESENCE_DETAIL_MAX_BYTES, DEFAULT_PRESENCE_MINIMUM_INTERVAL_MS, DEFAULT_PRESENCE_TTL_MS, DEFAULT_SKILL_PACK_PAGE_LIMIT, DEVICE_IDENTITY_PROOF_KEY_EPOCH, DEVICE_IDENTITY_PROOF_KEY_ID, InMemoryActivityStore, InMemoryAgentEgressStore, InMemoryAgentMemoryProjectionAuthorizer, InMemoryAgentMemoryProjectionStore, InMemoryBlobContentProxy, InMemoryCloudBlobStore, InMemoryDeviceDirectory, InMemoryInboundDedupStore, InMemoryNonceStore, InMemoryPairingCodeStore, InMemoryProofRequestReceiptStore, InMemoryRequestReceiptStore, InMemoryTaskAttemptStore, InMemoryTaskCancellationStore, MAX_DEVICE_PROOF_CLOCK_SKEW_MS, MAX_DEVICE_PROOF_HEADER_BYTES, MAX_DEVICE_PROOF_MAX_LIFETIME_MS, NONCE_TTL_MS, PAIRING_CODE_TTL_MS, ROUTE_CLASSES, ROUTE_METHODS, TASK_ATTEMPT_STATUSES, TRUTH_BATCH_MAX_RECORDS, TRUTH_INLINE_CONTENT_TYPE, TRUTH_LABEL_MAX_LENGTH, TRUTH_MANIFEST_MAX_LIMIT, TRUTH_RECORD_CAPABILITY, TRUTH_RECORD_KEY_MAX_LENGTH, TRUTH_REQUEST_ID_MAX_LENGTH, TimelineEventSchema, TruthBodyInputSchema, TruthCommitError, TruthCommitResponseSchema, TruthRecordKeySchema, TruthRecordMetadataSchema, TruthWriteRequestSchema, activityCursor, agentHomeProjectionCompletionKey, agentHomeProjectionRequestKey, approvalTimelineCursor, authenticateBearer, authenticateDeviceProof, authenticateHostedDeviceAssertion, createAuthPlane, createByokCloud, createHmacTokenSigner, createInMemoryBlobs, createInMemoryByokCloud, createInMemoryCloudStores, createWebCrypto, declares, extractBearerToken, fullCapabilityDeclaration, handleInboundEnvelope, isCloudError, isTruthCommitError, parseApprovalObservations, parseTimelineEvents, projectTerminalResult, projectTimelineEvents, readAgentHomeProjectionStatus, recordAgentHomeProjectionCompletion, routeKey, tenantStoresFor, terminalReceiptKey, truthManifestMetadata, truthRecordMetadata, validateActivityAppend, validateApprovalTimelineAppend, verifyNonceSignature };
3845
4318
  //# sourceMappingURL=index.js.map
3846
4319
  //# sourceMappingURL=index.js.map