@dungle-scrubs/tether-protocol 0.1.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.
@@ -0,0 +1,313 @@
1
+ import { z } from "zod";
2
+ import type { CandidateScheduleIdentity } from "./task-contracts.js";
3
+ /**
4
+ * Durable task record returned by Tether task APIs and embedded in task
5
+ * lifecycle events.
6
+ */
7
+ export interface TaskRecord {
8
+ /** Cancellation timestamp, when the task has been cancelled. */
9
+ readonly cancelledAt: string | null;
10
+ /** Claim-expiration timestamp persisted after the scheduler clears an elapsed claim. */
11
+ readonly claimExpiredAt: string | null;
12
+ /** Participant id whose claim elapsed, when the scheduler cleared it. */
13
+ readonly claimExpiredBy: string | null;
14
+ /** Claim lease expiry timestamp, when a claimed task should become claimable again. */
15
+ readonly claimExpiresAt: string | null;
16
+ /** Claim timestamp, when a participant runtime currently owns the task. */
17
+ readonly claimedAt: string | null;
18
+ /** Participant id currently claiming the task. */
19
+ readonly claimedBy: string | null;
20
+ /** Completion timestamp, when the task has completed successfully. */
21
+ readonly completedAt: string | null;
22
+ /** Creation timestamp returned by Tether. */
23
+ readonly createdAt: string;
24
+ /** Failure timestamp, when the task has reached a terminal failure. */
25
+ readonly failedAt: string | null;
26
+ /** Structured failure payload, when the task failed with details. */
27
+ readonly failure: Record<string, unknown> | null;
28
+ /** Structured task input supplied at creation time, when available. */
29
+ readonly input: Record<string, unknown> | null;
30
+ /** Task kind used by participant runtimes to decide claimability. */
31
+ readonly kind: string;
32
+ /** User-visible task objective. */
33
+ readonly objective: string;
34
+ /** Last claim release timestamp, when a participant explicitly released the task. */
35
+ readonly releasedAt: string | null;
36
+ /** Participant id that explicitly released the task claim. */
37
+ readonly releasedBy: string | null;
38
+ /** Structured result payload, when the task completed with details. */
39
+ readonly result: Record<string, unknown> | null;
40
+ /**
41
+ * Deterministic schedule and Mailbox Scope identity for scheduled maintenance
42
+ * runs; null for manual tasks. Present only when the durable row carries a
43
+ * complete Schedule Window and Mailbox Scope.
44
+ */
45
+ readonly schedule?: CandidateScheduleIdentity | null;
46
+ /** Durable Tether session that owns the task. */
47
+ readonly sessionId: string;
48
+ /** Durable task id. */
49
+ readonly taskId: string;
50
+ }
51
+ /** Public session event type names used by REST and WebSocket boundaries. */
52
+ export type SessionEventType = "agent.output" | "approval.recorded" | "control.cancel" | "participant.heartbeat" | "participant.joined" | "participant.updated" | "session.created" | "task.claim_expired" | "task.claimed" | "task.completed" | "task.created" | "task.failed" | "task.progress" | "task.released" | "user.message" | (string & {});
53
+ /** Runtime kind advertised by a participant. */
54
+ export type ParticipantRuntimeKind = "claude_code" | "codex" | "generic_agent" | "openai_agent" | "pi_coding_agent" | (string & {});
55
+ /** Control channel used by a participant runtime. */
56
+ export type ControlChannel = "rest" | "ws";
57
+ /** Durable event visible in one Tether session stream. */
58
+ export interface SessionEvent {
59
+ readonly createdAt: string;
60
+ readonly eventId: string;
61
+ readonly payload: Record<string, unknown>;
62
+ readonly producerId: string;
63
+ readonly seq: number;
64
+ readonly sessionId: string;
65
+ readonly type: SessionEventType;
66
+ }
67
+ /** Visible participant presence record. */
68
+ export interface ParticipantRecord {
69
+ readonly capabilities: Record<string, unknown>;
70
+ readonly displayName: string;
71
+ readonly joinedAt: string;
72
+ readonly lastSeenAt: string;
73
+ readonly participantId: string;
74
+ readonly runtimeKind: ParticipantRuntimeKind;
75
+ readonly sessionId: string;
76
+ }
77
+ /**
78
+ * Task lifecycle filter for user-facing task lists.
79
+ */
80
+ export type TaskListStatus = "active" | "all" | "terminal";
81
+ /** Durable Tether session row shared by service and adapter diagnostics. */
82
+ export interface SessionRecord {
83
+ /** Time this session was first created. */
84
+ readonly createdAt: string;
85
+ /** Durable session identifier. */
86
+ readonly sessionId: string;
87
+ }
88
+ /**
89
+ * Durable association between an external client conversation and one Tether
90
+ * session.
91
+ */
92
+ export interface ClientSessionBindingRecord {
93
+ /** Time this binding was archived, or null while active. */
94
+ readonly archivedAt: string | null;
95
+ /** Time this binding was first created. */
96
+ readonly createdAt: string;
97
+ /** Provider-specific conversation id, such as an external chat id. */
98
+ readonly externalId: string;
99
+ /** Most recent time a bridge resolved this binding. */
100
+ readonly lastSeenAt: string;
101
+ /** Client integration provider, such as `external-chat` or `slack`. */
102
+ readonly provider: string;
103
+ /** Durable Tether session associated with the external conversation. */
104
+ readonly sessionId: string;
105
+ }
106
+ /** Operator-facing state derived from the durable participant control lease. */
107
+ export type ControlLeaseStatus = "active" | "expired" | "released" | "superseded";
108
+ /** Read-only diagnostic view of one participant control lease. */
109
+ export interface ControlLeaseSnapshot {
110
+ /** When this runtime instance first claimed the participant control channel. */
111
+ readonly claimedAt: string;
112
+ /** Whether this runtime instance controls the participant through REST or WebSocket. */
113
+ readonly controlChannel: ControlChannel;
114
+ /** Immutable, strictly-monotonic server-issued Control Epoch for this lease. */
115
+ readonly epoch: number;
116
+ /** Concrete runtime process currently or formerly associated with the lease. */
117
+ readonly instanceId: string;
118
+ /** Most recent durable refresh observed for this lease. */
119
+ readonly lastSeenAt: string;
120
+ /** Time after which an unreleased lease no longer blocks another runtime. */
121
+ readonly leaseExpiresAt: string;
122
+ /** Participant identity controlled by this runtime instance. */
123
+ readonly participantId: string;
124
+ /** Time this lease was explicitly released, or null while unreleased. */
125
+ readonly releasedAt: string | null;
126
+ /** Session that owns this participant control lease. */
127
+ readonly sessionId: string;
128
+ /** Time this lease was superseded by another runtime, or null while current. */
129
+ readonly supersededAt: string | null;
130
+ /** Current derived lease state for operator diagnostics. */
131
+ readonly status: ControlLeaseStatus;
132
+ }
133
+ /** Operator-facing state derived from a durable task row. */
134
+ export type TaskSnapshotStatus = "cancelled" | "claim_active" | "claim_cleared" | "claim_expired" | "completed" | "failed" | "unclaimed";
135
+ /** Durable approval decision attached to one task target. */
136
+ export interface TaskApprovalRecord {
137
+ /** Event id of the corresponding `approval.recorded` event. */
138
+ readonly approvalEventId: string;
139
+ /** Time the winning approval decision was committed. */
140
+ readonly decidedAt: string;
141
+ /** Participant that issued the winning decision. */
142
+ readonly decidedByParticipantId: string;
143
+ /** Winning approval decision for the target. */
144
+ readonly decision: "approved" | "rejected";
145
+ /** Original approval reason used to derive the target key. */
146
+ readonly reason: Record<string, unknown>;
147
+ /** Session that owns the task. */
148
+ readonly sessionId: string;
149
+ /** Canonical durable approval target key. */
150
+ readonly targetKey: string;
151
+ /** Approved task id. */
152
+ readonly taskId: string;
153
+ }
154
+ /** Read-only diagnostic view of one task with derived lifecycle state. */
155
+ export interface TaskSnapshot extends TaskRecord {
156
+ /** Schema-backed approval decisions recorded for this task. */
157
+ readonly approvals: readonly TaskApprovalRecord[];
158
+ /** Current derived task state for operator diagnostics. */
159
+ readonly status: TaskSnapshotStatus;
160
+ }
161
+ /**
162
+ * Operator-facing state derived from visible participant presence and control
163
+ * lease state.
164
+ */
165
+ export type ParticipantRuntimeSnapshotStatus = "lease_without_presence" | "registered_control_active" | "registered_control_inactive" | "registered_without_control";
166
+ /**
167
+ * Read-only diagnostic view of a participant identity and the runtime instance
168
+ * that currently or most recently controlled it.
169
+ */
170
+ export interface ParticipantRuntimeSnapshot {
171
+ /** Number of durable control-lease rows associated with this participant. */
172
+ readonly controlLeaseCount: number;
173
+ /** Active control lease for this participant, or null when no runtime currently controls it. */
174
+ readonly currentControlLease: ControlLeaseSnapshot | null;
175
+ /** Most recently observed control lease for this participant, including inactive leases. */
176
+ readonly latestControlLease: ControlLeaseSnapshot | null;
177
+ /** Visible participant presence record, or null when only lease state exists. */
178
+ readonly participant: ParticipantRecord | null;
179
+ /** Participant identity being diagnosed. */
180
+ readonly participantId: string;
181
+ /** Whether this participant has visible presence in the session. */
182
+ readonly registered: boolean;
183
+ /** Session that owns the participant runtime state. */
184
+ readonly sessionId: string;
185
+ /** Current derived participant runtime state for operator diagnostics. */
186
+ readonly status: ParticipantRuntimeSnapshotStatus;
187
+ }
188
+ /** Participant counts in a session debug summary. */
189
+ export interface SessionDebugParticipantSummary {
190
+ /** Number of visible participant identities with an active control lease. */
191
+ readonly activeControl: number;
192
+ /** Number of participant identities represented only by lease state. */
193
+ readonly leaseOnly: number;
194
+ /** Number of visible participant identities. */
195
+ readonly registered: number;
196
+ /** Number of participant runtime snapshots in the summary. */
197
+ readonly total: number;
198
+ /** Number of visible participant identities without active control. */
199
+ readonly withoutActiveControl: number;
200
+ }
201
+ /** Control lease counts in a session debug summary. */
202
+ export interface SessionDebugControlLeaseSummary {
203
+ /** Number of unreleased control leases whose lease time has not elapsed. */
204
+ readonly active: number;
205
+ /** Number of unreleased control leases whose lease time has elapsed. */
206
+ readonly expired: number;
207
+ /** Number of explicitly released control leases. */
208
+ readonly released: number;
209
+ /** Number of control leases superseded by a later owner. */
210
+ readonly superseded: number;
211
+ /** Number of control lease snapshots in the summary. */
212
+ readonly total: number;
213
+ }
214
+ /** Task counts in a session debug summary. */
215
+ export interface SessionDebugTaskSummary {
216
+ /** Number of currently active task claims. */
217
+ readonly activeClaims: number;
218
+ /** Number of cancelled tasks. */
219
+ readonly cancelled: number;
220
+ /** Number of tasks that can be claimed without waiting for the scheduler. */
221
+ readonly claimable: number;
222
+ /** Number of active claim snapshots. */
223
+ readonly claimActive: number;
224
+ /** Number of cleared claim snapshots. */
225
+ readonly claimCleared: number;
226
+ /** Number of expired claim snapshots waiting for scheduler cleanup. */
227
+ readonly claimExpired: number;
228
+ /** Number of completed tasks. */
229
+ readonly completed: number;
230
+ /** Number of expired task claims waiting for scheduler cleanup. */
231
+ readonly expiredClaims: number;
232
+ /** Number of failed tasks. */
233
+ readonly failed: number;
234
+ /** Number of terminal tasks. */
235
+ readonly terminal: number;
236
+ /** Number of task snapshots in the summary. */
237
+ readonly total: number;
238
+ /** Number of unclaimed tasks. */
239
+ readonly unclaimed: number;
240
+ }
241
+ /** Read-only aggregate diagnostic view for one session. */
242
+ export interface SessionDebugSummary {
243
+ /** Participant runtime snapshot counts. */
244
+ readonly participants: SessionDebugParticipantSummary;
245
+ /** Control lease snapshot counts. */
246
+ readonly controlLeases: SessionDebugControlLeaseSummary;
247
+ /** Session being summarized. */
248
+ readonly sessionId: string;
249
+ /** Task snapshot counts. */
250
+ readonly tasks: SessionDebugTaskSummary;
251
+ }
252
+ /** Producer id used by Tether-owned system events. */
253
+ export declare const systemProducerId = "tether";
254
+ /** Canonical session event names. */
255
+ export declare const sessionEventType: {
256
+ readonly agentOutput: "agent.output";
257
+ readonly approvalRecorded: "approval.recorded";
258
+ readonly controlCancel: "control.cancel";
259
+ readonly participantHeartbeat: "participant.heartbeat";
260
+ readonly participantJoined: "participant.joined";
261
+ readonly participantUpdated: "participant.updated";
262
+ readonly sessionCreated: "session.created";
263
+ readonly taskClaimExpired: "task.claim_expired";
264
+ readonly taskClaimed: "task.claimed";
265
+ readonly taskCompleted: "task.completed";
266
+ readonly taskCreated: "task.created";
267
+ readonly taskFailed: "task.failed";
268
+ readonly taskProgress: "task.progress";
269
+ readonly taskReleased: "task.released";
270
+ readonly userMessage: "user.message";
271
+ };
272
+ /** Canonical WebSocket operation names. */
273
+ export declare const webSocketOperation: {
274
+ readonly commandResult: "command.result";
275
+ readonly error: "error";
276
+ readonly event: "event";
277
+ readonly publish: "publish";
278
+ readonly replayComplete: "replay.complete";
279
+ readonly taskCancel: "task.cancel";
280
+ readonly taskClaim: "task.claim";
281
+ readonly taskComplete: "task.complete";
282
+ readonly taskFail: "task.fail";
283
+ readonly taskRefresh: "task.refresh";
284
+ readonly taskRelease: "task.release";
285
+ };
286
+ /**
287
+ * Runtime validator for durable task records crossing REST and WebSocket
288
+ * protocol boundaries.
289
+ */
290
+ export declare const taskRecordSchema: z.ZodObject<{
291
+ cancelledAt: z.ZodNullable<z.ZodString>;
292
+ claimExpiredAt: z.ZodNullable<z.ZodString>;
293
+ claimExpiredBy: z.ZodNullable<z.ZodString>;
294
+ claimExpiresAt: z.ZodNullable<z.ZodString>;
295
+ claimedAt: z.ZodNullable<z.ZodString>;
296
+ claimedBy: z.ZodNullable<z.ZodString>;
297
+ completedAt: z.ZodNullable<z.ZodString>;
298
+ createdAt: z.ZodString;
299
+ failedAt: z.ZodNullable<z.ZodString>;
300
+ failure: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
301
+ input: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
302
+ kind: z.ZodString;
303
+ objective: z.ZodString;
304
+ releasedAt: z.ZodNullable<z.ZodString>;
305
+ releasedBy: z.ZodNullable<z.ZodString>;
306
+ result: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
307
+ sessionId: z.ZodString;
308
+ taskId: z.ZodString;
309
+ }, z.core.$strip>;
310
+ /** Runtime validator for participant control channels. */
311
+ export declare const controlChannelSchema: z.ZodUnion<readonly [z.ZodLiteral<"rest">, z.ZodLiteral<"ws">]>;
312
+ /** Runtime validator for participant runtime kinds. */
313
+ export declare const participantRuntimeKindSchema: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"claude_code">, z.ZodLiteral<"codex">, z.ZodLiteral<"generic_agent">, z.ZodLiteral<"openai_agent">, z.ZodLiteral<"pi_coding_agent">, z.ZodString]>>;
@@ -0,0 +1,72 @@
1
+ import { z } from "zod";
2
+ /** Producer id used by Tether-owned system events. */
3
+ export const systemProducerId = "tether";
4
+ /** Canonical session event names. */
5
+ export const sessionEventType = {
6
+ agentOutput: "agent.output",
7
+ approvalRecorded: "approval.recorded",
8
+ controlCancel: "control.cancel",
9
+ participantHeartbeat: "participant.heartbeat",
10
+ participantJoined: "participant.joined",
11
+ participantUpdated: "participant.updated",
12
+ sessionCreated: "session.created",
13
+ taskClaimExpired: "task.claim_expired",
14
+ taskClaimed: "task.claimed",
15
+ taskCompleted: "task.completed",
16
+ taskCreated: "task.created",
17
+ taskFailed: "task.failed",
18
+ taskProgress: "task.progress",
19
+ taskReleased: "task.released",
20
+ userMessage: "user.message",
21
+ };
22
+ /** Canonical WebSocket operation names. */
23
+ export const webSocketOperation = {
24
+ commandResult: "command.result",
25
+ error: "error",
26
+ event: "event",
27
+ publish: "publish",
28
+ replayComplete: "replay.complete",
29
+ taskCancel: "task.cancel",
30
+ taskClaim: "task.claim",
31
+ taskComplete: "task.complete",
32
+ taskFail: "task.fail",
33
+ taskRefresh: "task.refresh",
34
+ taskRelease: "task.release",
35
+ };
36
+ /**
37
+ * Runtime validator for durable task records crossing REST and WebSocket
38
+ * protocol boundaries.
39
+ */
40
+ export const taskRecordSchema = z.object({
41
+ cancelledAt: z.string().nullable(),
42
+ claimExpiredAt: z.string().nullable(),
43
+ claimExpiredBy: z.string().nullable(),
44
+ claimExpiresAt: z.string().nullable(),
45
+ claimedAt: z.string().nullable(),
46
+ claimedBy: z.string().nullable(),
47
+ completedAt: z.string().nullable(),
48
+ createdAt: z.string(),
49
+ failedAt: z.string().nullable(),
50
+ failure: z.record(z.string(), z.unknown()).nullable(),
51
+ input: z.record(z.string(), z.unknown()).nullable(),
52
+ kind: z.string().min(1),
53
+ objective: z.string().min(1),
54
+ releasedAt: z.string().nullable(),
55
+ releasedBy: z.string().nullable(),
56
+ result: z.record(z.string(), z.unknown()).nullable(),
57
+ sessionId: z.string().min(1),
58
+ taskId: z.string().min(1),
59
+ });
60
+ /** Runtime validator for participant control channels. */
61
+ export const controlChannelSchema = z.union([z.literal("rest"), z.literal("ws")]);
62
+ /** Runtime validator for participant runtime kinds. */
63
+ export const participantRuntimeKindSchema = z
64
+ .union([
65
+ z.literal("claude_code"),
66
+ z.literal("codex"),
67
+ z.literal("generic_agent"),
68
+ z.literal("openai_agent"),
69
+ z.literal("pi_coding_agent"),
70
+ z.string().min(1),
71
+ ])
72
+ .default("generic_agent");
@@ -0,0 +1,149 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Server-issued Control Epoch carried by control-protected REST requests. It is
4
+ * a positive safe integer; the server validates it against the current durable
5
+ * lease generation in the same transaction as the protected mutation.
6
+ */
7
+ export declare const controlEpochSchema: z.ZodNumber;
8
+ /** Pagination metadata returned by bounded session event-list responses. */
9
+ export declare const eventListPaginationSchema: z.ZodObject<{
10
+ afterSeq: z.ZodNumber;
11
+ hasMore: z.ZodBoolean;
12
+ limit: z.ZodNumber;
13
+ nextAfterSeq: z.ZodNumber;
14
+ returned: z.ZodNumber;
15
+ }, z.core.$strip>;
16
+ /** HTTP response schema for bounded session event-list responses. */
17
+ export declare const eventListResponseSchema: z.ZodObject<{
18
+ events: z.ZodArray<z.ZodLazy<z.ZodObject<{
19
+ createdAt: z.ZodString;
20
+ eventId: z.ZodString;
21
+ payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
22
+ producerId: z.ZodString;
23
+ seq: z.ZodNumber;
24
+ sessionId: z.ZodString;
25
+ type: z.ZodPipe<z.ZodString, z.ZodTransform<(string & {}) | "agent.output" | "approval.recorded" | "control.cancel" | "participant.heartbeat" | "participant.joined" | "participant.updated" | "session.created" | "task.claim_expired" | "task.claimed" | "task.completed" | "task.created" | "task.failed" | "task.progress" | "task.released" | "user.message", string>>;
26
+ }, z.core.$strip>>>;
27
+ pagination: z.ZodObject<{
28
+ afterSeq: z.ZodNumber;
29
+ hasMore: z.ZodBoolean;
30
+ limit: z.ZodNumber;
31
+ nextAfterSeq: z.ZodNumber;
32
+ returned: z.ZodNumber;
33
+ }, z.core.$strip>;
34
+ }, z.core.$strip>;
35
+ /** Pagination metadata returned by bounded session event-list responses. */
36
+ export type EventListPagination = z.infer<typeof eventListPaginationSchema>;
37
+ /** HTTP response body for bounded session event-list responses. */
38
+ export type EventListResponse = z.infer<typeof eventListResponseSchema>;
39
+ /** HTTP body schema for appending a generic session event. */
40
+ export declare const appendEventSchema: z.ZodObject<{
41
+ controlEpoch: z.ZodOptional<z.ZodNumber>;
42
+ eventId: z.ZodOptional<z.ZodString>;
43
+ instanceId: z.ZodOptional<z.ZodString>;
44
+ payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
45
+ producerId: z.ZodString;
46
+ type: z.ZodString;
47
+ }, z.core.$strip>;
48
+ /** HTTP body schema for session creation. */
49
+ export declare const createSessionSchema: z.ZodObject<{
50
+ sessionId: z.ZodOptional<z.ZodString>;
51
+ }, z.core.$strip>;
52
+ /** HTTP body schema for resolving external client conversations. */
53
+ export declare const resolveClientSessionSchema: z.ZodObject<{
54
+ externalId: z.ZodString;
55
+ provider: z.ZodString;
56
+ sessionId: z.ZodOptional<z.ZodString>;
57
+ }, z.core.$strip>;
58
+ /** HTTP body schema for participant registration. */
59
+ export declare const registerParticipantSchema: z.ZodObject<{
60
+ capabilities: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
61
+ controlChannel: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"rest">, z.ZodLiteral<"ws">]>>;
62
+ displayName: z.ZodOptional<z.ZodString>;
63
+ instanceId: z.ZodOptional<z.ZodString>;
64
+ participantId: z.ZodOptional<z.ZodString>;
65
+ runtimeKind: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"claude_code">, z.ZodLiteral<"codex">, z.ZodLiteral<"generic_agent">, z.ZodLiteral<"openai_agent">, z.ZodLiteral<"pi_coding_agent">, z.ZodString]>>;
66
+ }, z.core.$strip>;
67
+ /** HTTP body schema for participant heartbeat refresh. */
68
+ export declare const heartbeatParticipantSchema: z.ZodObject<{
69
+ capabilities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
70
+ controlEpoch: z.ZodOptional<z.ZodNumber>;
71
+ instanceId: z.ZodOptional<z.ZodString>;
72
+ }, z.core.$strip>;
73
+ /** HTTP body schema for task creation. */
74
+ /**
75
+ * Deterministic schedule and Mailbox Scope identity a scheduled maintenance run
76
+ * carries at creation. Interval and algorithm version are part of task identity.
77
+ */
78
+ export declare const scheduledTaskIdentitySchema: z.ZodObject<{
79
+ mailboxAccountId: z.ZodString;
80
+ mailboxProvider: z.ZodString;
81
+ scheduleAlgorithmVersion: z.ZodNumber;
82
+ scheduleIntervalMs: z.ZodNumber;
83
+ scheduleWindowStart: z.ZodNumber;
84
+ }, z.core.$strip>;
85
+ export declare const createTaskSchema: z.ZodObject<{
86
+ input: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
87
+ kind: z.ZodString;
88
+ objective: z.ZodString;
89
+ requireContract: z.ZodOptional<z.ZodBoolean>;
90
+ schedule: z.ZodOptional<z.ZodObject<{
91
+ mailboxAccountId: z.ZodString;
92
+ mailboxProvider: z.ZodString;
93
+ scheduleAlgorithmVersion: z.ZodNumber;
94
+ scheduleIntervalMs: z.ZodNumber;
95
+ scheduleWindowStart: z.ZodNumber;
96
+ }, z.core.$strip>>;
97
+ taskId: z.ZodOptional<z.ZodString>;
98
+ }, z.core.$strip>;
99
+ /** HTTP body schema for task claim. */
100
+ export declare const claimTaskSchema: z.ZodObject<{
101
+ controlEpoch: z.ZodOptional<z.ZodNumber>;
102
+ instanceId: z.ZodOptional<z.ZodString>;
103
+ participantId: z.ZodString;
104
+ }, z.core.$strip>;
105
+ /** HTTP body schema for task claim refresh. */
106
+ export declare const refreshTaskClaimSchema: z.ZodObject<{
107
+ controlEpoch: z.ZodOptional<z.ZodNumber>;
108
+ instanceId: z.ZodOptional<z.ZodString>;
109
+ participantId: z.ZodString;
110
+ }, z.core.$strip>;
111
+ /** HTTP body schema for task cancellation. */
112
+ export declare const cancelTaskSchema: z.ZodObject<{
113
+ controlEpoch: z.ZodOptional<z.ZodNumber>;
114
+ instanceId: z.ZodOptional<z.ZodString>;
115
+ participantId: z.ZodString;
116
+ reason: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
117
+ }, z.core.$strip>;
118
+ /** HTTP body schema for task completion. */
119
+ export declare const completeTaskSchema: z.ZodObject<{
120
+ controlEpoch: z.ZodOptional<z.ZodNumber>;
121
+ instanceId: z.ZodOptional<z.ZodString>;
122
+ participantId: z.ZodString;
123
+ result: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
124
+ }, z.core.$strip>;
125
+ /** HTTP body schema for task failure. */
126
+ export declare const failTaskSchema: z.ZodObject<{
127
+ controlEpoch: z.ZodOptional<z.ZodNumber>;
128
+ failure: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
129
+ instanceId: z.ZodOptional<z.ZodString>;
130
+ participantId: z.ZodString;
131
+ }, z.core.$strip>;
132
+ /** HTTP body schema for task claim release. */
133
+ export declare const releaseTaskSchema: z.ZodObject<{
134
+ controlEpoch: z.ZodOptional<z.ZodNumber>;
135
+ instanceId: z.ZodOptional<z.ZodString>;
136
+ participantId: z.ZodString;
137
+ }, z.core.$strip>;
138
+ /** Schema for durable task approval decisions. */
139
+ export declare const approvalDecisionSchema: z.ZodUnion<readonly [z.ZodLiteral<"approved">, z.ZodLiteral<"rejected">]>;
140
+ /** Durable approval decision values recorded in session events. */
141
+ export type ApprovalDecision = z.infer<typeof approvalDecisionSchema>;
142
+ /** HTTP payload schema for recording approval intent for a task. */
143
+ export declare const recordTaskApprovalSchema: z.ZodObject<{
144
+ controlEpoch: z.ZodOptional<z.ZodNumber>;
145
+ decision: z.ZodUnion<readonly [z.ZodLiteral<"approved">, z.ZodLiteral<"rejected">]>;
146
+ instanceId: z.ZodOptional<z.ZodString>;
147
+ participantId: z.ZodString;
148
+ reason: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
149
+ }, z.core.$strip>;
@@ -0,0 +1,131 @@
1
+ import { z } from "zod";
2
+ import { sessionEventSchema } from "./event-builders.js";
3
+ import { controlChannelSchema, participantRuntimeKindSchema } from "./records.js";
4
+ /**
5
+ * Server-issued Control Epoch carried by control-protected REST requests. It is
6
+ * a positive safe integer; the server validates it against the current durable
7
+ * lease generation in the same transaction as the protected mutation.
8
+ */
9
+ export const controlEpochSchema = z
10
+ .number()
11
+ .int()
12
+ .positive()
13
+ .refine((value) => Number.isSafeInteger(value), {
14
+ message: "controlEpoch must be a positive safe integer",
15
+ });
16
+ /** Pagination metadata returned by bounded session event-list responses. */
17
+ export const eventListPaginationSchema = z.object({
18
+ afterSeq: z.number().int().nonnegative(),
19
+ hasMore: z.boolean(),
20
+ limit: z.number().int().positive(),
21
+ nextAfterSeq: z.number().int().nonnegative(),
22
+ returned: z.number().int().nonnegative(),
23
+ });
24
+ /** HTTP response schema for bounded session event-list responses. */
25
+ export const eventListResponseSchema = z.object({
26
+ events: z.array(z.lazy(() => sessionEventSchema)),
27
+ pagination: eventListPaginationSchema,
28
+ });
29
+ /** HTTP body schema for appending a generic session event. */
30
+ export const appendEventSchema = z.object({
31
+ controlEpoch: controlEpochSchema.optional(),
32
+ eventId: z.string().min(1).optional(),
33
+ instanceId: z.string().min(1).optional(),
34
+ payload: z.record(z.string(), z.unknown()).default({}),
35
+ producerId: z.string().min(1),
36
+ type: z.string().min(1),
37
+ });
38
+ /** HTTP body schema for session creation. */
39
+ export const createSessionSchema = z.object({
40
+ sessionId: z.string().min(1).optional(),
41
+ });
42
+ /** HTTP body schema for resolving external client conversations. */
43
+ export const resolveClientSessionSchema = z.object({
44
+ externalId: z.string().min(1),
45
+ provider: z.string().min(1),
46
+ sessionId: z.string().min(1).optional(),
47
+ });
48
+ /** HTTP body schema for participant registration. */
49
+ export const registerParticipantSchema = z.object({
50
+ capabilities: z.record(z.string(), z.unknown()).default({}),
51
+ controlChannel: controlChannelSchema.default("rest"),
52
+ displayName: z.string().min(1).optional(),
53
+ instanceId: z.string().min(1).optional(),
54
+ participantId: z.string().min(1).optional(),
55
+ runtimeKind: participantRuntimeKindSchema,
56
+ });
57
+ /** HTTP body schema for participant heartbeat refresh. */
58
+ export const heartbeatParticipantSchema = z.object({
59
+ capabilities: z.record(z.string(), z.unknown()).optional(),
60
+ controlEpoch: controlEpochSchema.optional(),
61
+ instanceId: z.string().min(1).optional(),
62
+ });
63
+ /** HTTP body schema for task creation. */
64
+ /**
65
+ * Deterministic schedule and Mailbox Scope identity a scheduled maintenance run
66
+ * carries at creation. Interval and algorithm version are part of task identity.
67
+ */
68
+ export const scheduledTaskIdentitySchema = z.object({
69
+ mailboxAccountId: z.string().min(1),
70
+ mailboxProvider: z.string().min(1),
71
+ scheduleAlgorithmVersion: z.number().int().positive(),
72
+ scheduleIntervalMs: z.number().int().positive(),
73
+ scheduleWindowStart: z.number().int().nonnegative(),
74
+ });
75
+ export const createTaskSchema = z.object({
76
+ input: z.record(z.string(), z.unknown()).nullable().optional(),
77
+ kind: z.string().min(1),
78
+ objective: z.string().min(1),
79
+ requireContract: z.boolean().optional(),
80
+ schedule: scheduledTaskIdentitySchema.optional(),
81
+ taskId: z.string().min(1).optional(),
82
+ });
83
+ /** HTTP body schema for task claim. */
84
+ export const claimTaskSchema = z.object({
85
+ controlEpoch: controlEpochSchema.optional(),
86
+ instanceId: z.string().min(1).optional(),
87
+ participantId: z.string().min(1),
88
+ });
89
+ /** HTTP body schema for task claim refresh. */
90
+ export const refreshTaskClaimSchema = z.object({
91
+ controlEpoch: controlEpochSchema.optional(),
92
+ instanceId: z.string().min(1).optional(),
93
+ participantId: z.string().min(1),
94
+ });
95
+ /** HTTP body schema for task cancellation. */
96
+ export const cancelTaskSchema = z.object({
97
+ controlEpoch: controlEpochSchema.optional(),
98
+ instanceId: z.string().min(1).optional(),
99
+ participantId: z.string().min(1),
100
+ reason: z.record(z.string(), z.unknown()).default({}),
101
+ });
102
+ /** HTTP body schema for task completion. */
103
+ export const completeTaskSchema = z.object({
104
+ controlEpoch: controlEpochSchema.optional(),
105
+ instanceId: z.string().min(1).optional(),
106
+ participantId: z.string().min(1),
107
+ result: z.record(z.string(), z.unknown()).default({}),
108
+ });
109
+ /** HTTP body schema for task failure. */
110
+ export const failTaskSchema = z.object({
111
+ controlEpoch: controlEpochSchema.optional(),
112
+ failure: z.record(z.string(), z.unknown()).default({}),
113
+ instanceId: z.string().min(1).optional(),
114
+ participantId: z.string().min(1),
115
+ });
116
+ /** HTTP body schema for task claim release. */
117
+ export const releaseTaskSchema = z.object({
118
+ controlEpoch: controlEpochSchema.optional(),
119
+ instanceId: z.string().min(1).optional(),
120
+ participantId: z.string().min(1),
121
+ });
122
+ /** Schema for durable task approval decisions. */
123
+ export const approvalDecisionSchema = z.union([z.literal("approved"), z.literal("rejected")]);
124
+ /** HTTP payload schema for recording approval intent for a task. */
125
+ export const recordTaskApprovalSchema = z.object({
126
+ controlEpoch: controlEpochSchema.optional(),
127
+ decision: approvalDecisionSchema,
128
+ instanceId: z.string().min(1).optional(),
129
+ participantId: z.string().min(1),
130
+ reason: z.record(z.string(), z.unknown()).default({}),
131
+ });