@byok-sdk/cloud 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/inbound.d.ts CHANGED
@@ -13,24 +13,61 @@
13
13
  * authenticated long-poll `conn.hello` capability snapshot handled below.
14
14
  * A server -> daemon type arriving inbound, or anything unrecognized, is
15
15
  * rejected before it is dispatched or counted accepted.
16
- * 2. **ownership** — an envelope for a task already owned by a DIFFERENT
17
- * device is dropped, never force-failed: force-failing on an authz mismatch
16
+ * 2. **ownership** — an envelope must name an existing task targeted at this
17
+ * exact device, and a task already owned by a DIFFERENT device is dropped,
18
+ * never force-failed: force-failing on an authz mismatch
18
19
  * would let an attacker who merely guesses a `taskId` kill the real owner's
19
- * task. A task with no owner yet, or that this tenant does not have at all,
20
- * is not rejected here — the store's own no-op-on-missing behavior covers
21
- * the latter, and it covers it per tenant, so a guessed id from another
22
- * tenant writes nothing anywhere.
23
- * 3. **dedup** — an envelope id already seen from this device is a no-op. The
24
- * wire is at-least-once (§9); this makes processing at-most-once.
25
- * 4. **apply** — the lifecycle write.
20
+ * task. Unknown task ids are rejected before any task-scoped projection or
21
+ * dedup fact can be written.
22
+ * 3. **apply/recover** — every lifecycle side effect is idempotent under the
23
+ * envelope's own durable identity. A retry after a partial failure resumes
24
+ * this step rather than being hidden by transport admission.
25
+ * 4. **dedup** — only after every authoritative side effect converged do we
26
+ * mark the envelope complete. The next retry is then a no-op.
26
27
  *
27
28
  * A duplicate is still a wire-level success (§8.2): it just did not re-run
28
29
  * anything. Only `rejected`/`rate_limited` are excluded from `accepted`.
30
+ *
31
+ * 5. **observe** — an optional {@link ByokCloudObserver} is told, once, about
32
+ * each envelope whose write committed. It runs after step 4 has returned,
33
+ * it cannot change the outcome, and it is not the admission hook.
29
34
  */
30
35
  import { type AgentMessageDispositionPayload, type AgentMessagePublishPayload, type AgentMessageServerContext, type Envelope } from '@byok-sdk/protocol';
36
+ import type { TenantId } from '@byok-sdk/core';
31
37
  import { type ActivityBounds } from './coordination';
32
38
  import type { TenantStores } from './tenant-stores';
33
39
  export type InboundOutcome = 'accepted' | 'duplicate' | 'rejected' | 'rate_limited';
40
+ /**
41
+ * One envelope whose write COMMITTED, handed to {@link ByokCloudObserver}.
42
+ *
43
+ * `outcome` is constant by construction — `accepted` is the only outcome that
44
+ * committed anything — and is carried anyway because it names the fact in the
45
+ * gate's own vocabulary rather than leaving the reader to infer it from the
46
+ * hook's name. A `duplicate` re-ran nothing, a `rejected` and a `rate_limited`
47
+ * wrote nothing; none of them appear here.
48
+ */
49
+ export interface InboundCommitted {
50
+ readonly tenantId: TenantId;
51
+ readonly deviceId: string;
52
+ readonly envelope: Envelope;
53
+ readonly outcome: Extract<InboundOutcome, 'accepted'>;
54
+ }
55
+ /**
56
+ * Post-commit relay for the host (the `TaskHandle` fan-out `@byok-sdk/server`
57
+ * drives off its live hub).
58
+ *
59
+ * Deliberately NOT the admission hook. `ByokCloudOptions.agentMessage.consume`
60
+ * runs BEFORE a write and decides whether it happens; this runs AFTER one and
61
+ * cannot decide anything: it returns `void`, it is called inside a `try`, and
62
+ * a throw from it is swallowed with the outcome already fixed. An observer
63
+ * that wants to refuse work has the admission hook; an observer here is
64
+ * watching, not gating.
65
+ *
66
+ * Synchronous and cheap by contract — it runs inline on the request path.
67
+ */
68
+ export interface ByokCloudObserver {
69
+ onInboundCommitted(input: InboundCommitted): void;
70
+ }
34
71
  export declare function handleAgentMessagePublish(stores: TenantStores, deviceId: string, taskId: string, payload: AgentMessagePublishPayload, consume: ((input: {
35
72
  readonly tenant: TenantStores['tenant'];
36
73
  readonly deviceId: string;
@@ -48,4 +85,4 @@ export declare function handleAgentMessagePublish(stores: TenantStores, deviceId
48
85
  export declare function readAgentMessageDisposition(stores: TenantStores, deviceId: string, taskId: string, payload: AgentMessagePublishPayload): Promise<AgentMessageDispositionPayload | undefined>;
49
86
  /** Receipt key a task's terminal is recorded under — the idempotency seam S3b's journal will share. */
50
87
  export declare function terminalReceiptKey(taskId: string): string;
51
- export declare function handleInboundEnvelope(stores: TenantStores, deviceId: string, envelope: Envelope, activityBounds?: ActivityBounds, agentMessageConsume?: Parameters<typeof handleAgentMessagePublish>[4]): Promise<InboundOutcome>;
88
+ export declare function handleInboundEnvelope(stores: TenantStores, deviceId: string, envelope: Envelope, activityBounds?: ActivityBounds, agentMessageConsume?: Parameters<typeof handleAgentMessagePublish>[4], observer?: ByokCloudObserver): Promise<InboundOutcome>;
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@
15
15
  export { isTenantId, tenantId } from '@byok-sdk/core';
16
16
  export type { TenantId } from '@byok-sdk/core';
17
17
  export { createByokCloud } from './cloud';
18
- export type { ByokCloud, ByokCloudOptions, AgentDispatchInput, AgentEgressDispatchInput, AgentEgressFreshSessionDispatchInput, AgentContentReadInput, AgentHomeProjectionInput, AgentHomeProjectionStatusInput, EnqueueOfferInput, EnqueueToolsetOfferInput, EnqueuedAgentControl, EnqueuedAgentHomeProjection, EnqueuedOffer, } from './cloud';
18
+ export type { ByokCloud, ByokCloudOptions, AgentDispatchInput, AgentEgressDispatchInput, AgentEgressFreshSessionDispatchInput, AgentContentReadInput, AgentHomeProjectionInput, AgentHomeProjectionStatusInput, ApproveTaskOptions, EnqueueOfferInput, EnqueueToolsetOfferInput, RejectTaskOptions, EnqueuedAgentControl, EnqueuedAgentHomeProjection, EnqueuedOffer, } from './cloud';
19
19
  export { agentHomeProjectionCompletionKey, agentHomeProjectionRequestKey, readAgentHomeProjectionStatus, recordAgentHomeProjectionCompletion, } from './agent-home-projections';
20
20
  export type { AgentHomeProjectionReceiptInput } from './agent-home-projections';
21
21
  export { AGENT_HOME_CONTRACT_CAPABILITY, DEFAULT_EVENTS_PAGE_LIMIT, DEFAULT_LONG_POLL_HOLD_MS, DEFAULT_LONG_POLL_INTERVAL_MS, DEFAULT_MAX_BLOB_SIZE_BYTES, } from './cloud';
@@ -45,16 +45,20 @@ export type { AuthPlane, AuthPlaneDeps, MintedAccessToken, PairInput } from './a
45
45
  export { createWebCrypto } from './crypto/web-crypto';
46
46
  export type { CloudCrypto } from './crypto/port';
47
47
  export { handleInboundEnvelope, terminalReceiptKey } from './inbound';
48
- export type { InboundOutcome } from './inbound';
48
+ export type { ByokCloudObserver, InboundCommitted, InboundOutcome } from './inbound';
49
49
  export { projectTerminalResult } from './terminal-result';
50
50
  export type { TerminalResult } from './terminal-result';
51
51
  export { tenantStoresFor } from './tenant-stores';
52
52
  export type { TenantBoundActivity, TenantBoundApprovalTimeline, TenantBoundBoard, CloudRootStores, TenantBoundBlobs, TenantBoundDedup, TenantBoundDevices, TenantBoundMailbox, TenantBoundPresence, TenantBoundQuota, TenantBoundRateLimiter, TenantBoundReceipts, TenantBoundTaskAttempts, TenantStores, } from './tenant-stores';
53
- export { ApprovalObservationSchema, ApprovalTimelineEventSchema, APPROVAL_SUMMARY_MAX_BYTES, DEFAULT_APPROVAL_TIMELINE_CAPACITY, DEFAULT_APPROVAL_TIMELINE_TTL_MS, approvalTimelineCursor, parseApprovalObservations, validateApprovalTimelineAppend, } from './approval-timeline';
54
- export type { ApprovalObservation, ApprovalTimelineAppendInput, ApprovalTimelineEvent, ApprovalTimelineStore, ApprovalTimelineTail, } from './approval-timeline';
55
- export { DEFAULT_ACTIVITY_BOUNDS, DEFAULT_ACTIVITY_CAPACITY, DEFAULT_ACTIVITY_MAX_BYTES, DEFAULT_ACTIVITY_MAX_EVENTS, DEFAULT_ACTIVITY_TTL_MS, DEFAULT_BOARD_CHANNEL_MAX_BYTES, DEFAULT_BOARD_TITLE_MAX_BYTES, DEFAULT_PRESENCE_DETAIL_MAX_BYTES, DEFAULT_PRESENCE_MINIMUM_INTERVAL_MS, DEFAULT_PRESENCE_TTL_MS, } from './coordination';
53
+ export { ApprovalObservationSchema, ApprovalTimelineEventSchema, APPROVAL_SUMMARY_MAX_BYTES, DEFAULT_APPROVAL_TIMELINE_CAPACITY, DEFAULT_APPROVAL_TIMELINE_TTL_MS, approvalTimelineCursor, parseApprovalObservations, validateApprovalTimelineAppend, validateApprovalTimelineResolve, } from './approval-timeline';
54
+ export type { ApprovalObservation, ApprovalTimelineAppendInput, ApprovalTimelineEvent, ApprovalTimelineResolvePendingInput, ApprovalTimelineResolvePendingResult, ApprovalTimelineStore, ApprovalTimelineTail, } from './approval-timeline';
55
+ export { StaleApprovalError, pendingApproval } from './approval-control';
56
+ export type { PendingApproval } from './approval-control';
57
+ export { SteerRejectedError } from './steer-control';
58
+ export type { SteerRejectionCode } from './steer-control';
59
+ export { assertTaskAttemptListLimit, DEFAULT_ACTIVITY_BOUNDS, DEFAULT_ACTIVITY_CAPACITY, DEFAULT_ACTIVITY_MAX_BYTES, DEFAULT_ACTIVITY_MAX_EVENTS, DEFAULT_ACTIVITY_TTL_MS, DEFAULT_BOARD_CHANNEL_MAX_BYTES, DEFAULT_BOARD_TITLE_MAX_BYTES, DEFAULT_PRESENCE_DETAIL_MAX_BYTES, DEFAULT_PRESENCE_MINIMUM_INTERVAL_MS, DEFAULT_PRESENCE_TTL_MS, } from './coordination';
56
60
  export type { ActivityBounds } from './coordination';
57
- export { TimelineEventSchema, ActivityAppendRequestSchema, activityCursor, parseTimelineEvents, projectTimelineEvents, validateActivityAppend, } from './activity';
61
+ export { TimelineEventSchema, ActivityAppendRequestSchema, activityCursor, activitySourceBatchState, parseTimelineEvents, projectTimelineEvents, validateActivityAppend, } from './activity';
58
62
  export type { ActivityAppendInput, ActivityCursor, ActivityStore, ActivityTail, TimelineEvent, } from './activity';
59
63
  export { BoardFeedClient, BoardFeedRetryableError, BoardFeedStoppedError } from './coordination-client';
60
64
  export type { BoardFeedClientOptions, BoardFeedItem, BoardFeedMode, BoardFeedPage, BoardFeedRead, } from './coordination-client';
@@ -65,6 +69,6 @@ export { TruthCommitError, isTruthCommitError } from './truth/errors';
65
69
  export type { TruthCommitErrorCode } from './truth/errors';
66
70
  export { BLOB_READ_ERROR_CODES, CLOUD_STORE_NAMES, TASK_ATTEMPT_STATUSES, } from './stores/ports';
67
71
  export { CLOUD_PORT_INTERFACES, CLOUD_PORT_METHODS } from './stores/ports-contract';
68
- export type { BlobContent, BlobContentProxy, BlobDeclaration, BlobObservation, BlobReadErrorCode, BlobReadResult, BlobWriteResult, CloudBlobStore, CloudStoreName, CloudStores, DeviceDirectory, DeviceRecord, DeviceRegistration, InboundDedupStore, InboundRateLimiter, NonceStore, PairingCodeClaims, PairingCodeInfo, PairingCodeIssueInput, PairingCodeStore, PairingEnrollment, PairingEnrollmentInput, ProofRequestReceipt, ProofRequestReceiptInput, ProofRequestReceiptStore, RequestReceipt, RequestReceiptStore, TaskAttempt, TaskAttemptStatus, TaskAttemptStore, AgentRef, AgentEgressRecord, AgentEgressStore, AgentMessageAdmission, TaskCancellationMutation, TaskCancellationRequest, TaskCancellationStore, } from './stores/ports';
72
+ export type { BlobContent, BlobContentProxy, BlobDeclaration, BlobObservation, BlobReadErrorCode, BlobReadResult, BlobWriteResult, CloudBlobStore, CloudStoreName, CloudStores, DeviceDirectory, DeviceRecord, DeviceRegistration, InboundDedupStore, InboundRateLimiter, NonceStore, PairingCodeClaims, PairingCodeInfo, PairingCodeIssueInput, PairingCodeStore, PairingEnrollment, PairingEnrollmentInput, ProofRequestReceipt, ProofRequestReceiptInput, ProofRequestReceiptStore, RequestReceipt, RequestReceiptStore, TaskAttempt, TaskAttemptListQuery, TaskAttemptPage, TaskAttemptStatus, TaskAttemptStore, AgentRef, AgentEgressRecord, AgentEgressStore, AgentMessageAdmission, TaskCancellationMutation, TaskCancellationRequest, TaskCancellationStore, } from './stores/ports';
69
73
  export { AllowAllRateLimiter, BLOB_URL_TTL_MS, DEDUP_RING_CAPACITY, InMemoryBlobContentProxy, InMemoryCloudBlobStore, InMemoryActivityStore, InMemoryDeviceDirectory, InMemoryInboundDedupStore, InMemoryNonceStore, InMemoryPairingCodeStore, InMemoryRequestReceiptStore, InMemoryAgentEgressStore, InMemoryProofRequestReceiptStore, InMemoryTaskAttemptStore, InMemoryTaskCancellationStore, NONCE_TTL_MS, createInMemoryBlobs, createInMemoryCloudStores, } from './stores/in-memory/index';
70
74
  export type { InMemoryBlobStoreOptions, InMemoryBlobs, InMemoryCloudComposition, } from './stores/in-memory/index';