@cleocode/contracts 2026.6.12 → 2026.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/dist/__tests__/operation-def.test.js +5 -1
  2. package/dist/__tests__/operation-def.test.js.map +1 -1
  3. package/dist/__tests__/provider-def.test.d.ts +12 -0
  4. package/dist/__tests__/provider-def.test.d.ts.map +1 -0
  5. package/dist/__tests__/provider-def.test.js +84 -0
  6. package/dist/__tests__/provider-def.test.js.map +1 -0
  7. package/dist/__tests__/sealed-credential.test.d.ts +19 -0
  8. package/dist/__tests__/sealed-credential.test.d.ts.map +1 -0
  9. package/dist/__tests__/sealed-credential.test.js +74 -0
  10. package/dist/__tests__/sealed-credential.test.js.map +1 -0
  11. package/dist/__tests__/service-provider.test.d.ts +17 -0
  12. package/dist/__tests__/service-provider.test.d.ts.map +1 -0
  13. package/dist/__tests__/service-provider.test.js +108 -0
  14. package/dist/__tests__/service-provider.test.js.map +1 -0
  15. package/dist/__tests__/skill-executor-contract.test.js +3 -0
  16. package/dist/__tests__/skill-executor-contract.test.js.map +1 -1
  17. package/dist/acceptance-gate.d.ts +2 -3
  18. package/dist/acceptance-gate.d.ts.map +1 -1
  19. package/dist/boundary.d.ts +52 -0
  20. package/dist/boundary.d.ts.map +1 -1
  21. package/dist/boundary.js +24 -19
  22. package/dist/boundary.js.map +1 -1
  23. package/dist/conduit.d.ts +171 -0
  24. package/dist/conduit.d.ts.map +1 -1
  25. package/dist/config/index.d.ts +23 -0
  26. package/dist/config/index.d.ts.map +1 -0
  27. package/dist/config/index.js +22 -0
  28. package/dist/config/index.js.map +1 -0
  29. package/dist/config.d.ts +104 -1
  30. package/dist/config.d.ts.map +1 -1
  31. package/dist/data-accessor.d.ts +21 -1
  32. package/dist/data-accessor.d.ts.map +1 -1
  33. package/dist/data-accessor.js.map +1 -1
  34. package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.d.ts +21 -0
  35. package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.d.ts.map +1 -0
  36. package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js +84 -0
  37. package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js.map +1 -0
  38. package/dist/dispatch/identity.d.ts +1 -1
  39. package/dist/dispatch/identity.d.ts.map +1 -1
  40. package/dist/dispatch/identity.js +25 -0
  41. package/dist/dispatch/identity.js.map +1 -1
  42. package/dist/dispatch/operation-def.d.ts +20 -0
  43. package/dist/dispatch/operation-def.d.ts.map +1 -1
  44. package/dist/dispatch/operations-registry.d.ts.map +1 -1
  45. package/dist/dispatch/operations-registry.js +1044 -182
  46. package/dist/dispatch/operations-registry.js.map +1 -1
  47. package/dist/docs/read.d.ts +2 -2
  48. package/dist/index.d.ts +25 -11
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +17 -1
  51. package/dist/index.js.map +1 -1
  52. package/dist/lease-ipc/__tests__/freeze.test.d.ts +15 -0
  53. package/dist/lease-ipc/__tests__/freeze.test.d.ts.map +1 -0
  54. package/dist/lease-ipc/__tests__/freeze.test.js +313 -0
  55. package/dist/lease-ipc/__tests__/freeze.test.js.map +1 -0
  56. package/dist/lease-ipc/index.d.ts +17 -0
  57. package/dist/lease-ipc/index.d.ts.map +1 -0
  58. package/dist/lease-ipc/index.js +16 -0
  59. package/dist/lease-ipc/index.js.map +1 -0
  60. package/dist/lease-ipc/messages.d.ts +918 -0
  61. package/dist/lease-ipc/messages.d.ts.map +1 -0
  62. package/dist/lease-ipc/messages.js +476 -0
  63. package/dist/lease-ipc/messages.js.map +1 -0
  64. package/dist/lease-ipc/version.d.ts +41 -0
  65. package/dist/lease-ipc/version.d.ts.map +1 -0
  66. package/dist/lease-ipc/version.js +43 -0
  67. package/dist/lease-ipc/version.js.map +1 -0
  68. package/dist/llm/catalog-schema.d.ts +242 -0
  69. package/dist/llm/catalog-schema.d.ts.map +1 -0
  70. package/dist/llm/catalog-schema.js +153 -0
  71. package/dist/llm/catalog-schema.js.map +1 -0
  72. package/dist/llm/catalog-schema.json +139 -0
  73. package/dist/llm/index.d.ts +15 -0
  74. package/dist/llm/index.d.ts.map +1 -0
  75. package/dist/llm/index.js +14 -0
  76. package/dist/llm/index.js.map +1 -0
  77. package/dist/llm/interfaces.d.ts +23 -0
  78. package/dist/llm/interfaces.d.ts.map +1 -1
  79. package/dist/llm/oauth.d.ts +16 -2
  80. package/dist/llm/oauth.d.ts.map +1 -1
  81. package/dist/llm/onboarding.d.ts +126 -0
  82. package/dist/llm/onboarding.d.ts.map +1 -0
  83. package/dist/llm/onboarding.js +34 -0
  84. package/dist/llm/onboarding.js.map +1 -0
  85. package/dist/llm/provider-def.d.ts +254 -0
  86. package/dist/llm/provider-def.d.ts.map +1 -0
  87. package/dist/llm/provider-def.js +93 -0
  88. package/dist/llm/provider-def.js.map +1 -0
  89. package/dist/llm/sealed-credential.d.ts +164 -0
  90. package/dist/llm/sealed-credential.d.ts.map +1 -0
  91. package/dist/llm/sealed-credential.js +43 -0
  92. package/dist/llm/sealed-credential.js.map +1 -0
  93. package/dist/llm/system-of-use.d.ts +383 -0
  94. package/dist/llm/system-of-use.d.ts.map +1 -0
  95. package/dist/llm/system-of-use.js +238 -0
  96. package/dist/llm/system-of-use.js.map +1 -0
  97. package/dist/llm/system-resolver.d.ts +87 -11
  98. package/dist/llm/system-resolver.d.ts.map +1 -1
  99. package/dist/llm/system-resolver.js +14 -7
  100. package/dist/llm/system-resolver.js.map +1 -1
  101. package/dist/operations/__tests__/ensures-schema-registry.test.d.ts +17 -0
  102. package/dist/operations/__tests__/ensures-schema-registry.test.d.ts.map +1 -0
  103. package/dist/operations/__tests__/ensures-schema-registry.test.js +113 -0
  104. package/dist/operations/__tests__/ensures-schema-registry.test.js.map +1 -0
  105. package/dist/operations/admin.d.ts +124 -1
  106. package/dist/operations/admin.d.ts.map +1 -1
  107. package/dist/operations/ensures-schema-registry.d.ts +172 -0
  108. package/dist/operations/ensures-schema-registry.d.ts.map +1 -0
  109. package/dist/operations/ensures-schema-registry.js +226 -0
  110. package/dist/operations/ensures-schema-registry.js.map +1 -0
  111. package/dist/operations/entities.d.ts +110 -0
  112. package/dist/operations/entities.d.ts.map +1 -0
  113. package/dist/operations/entities.js +695 -0
  114. package/dist/operations/entities.js.map +1 -0
  115. package/dist/operations/llm.d.ts +116 -9
  116. package/dist/operations/llm.d.ts.map +1 -1
  117. package/dist/operations/output-contracts-data.d.ts.map +1 -1
  118. package/dist/operations/output-contracts-data.js +230 -0
  119. package/dist/operations/output-contracts-data.js.map +1 -1
  120. package/dist/operations/service.d.ts +68 -0
  121. package/dist/operations/service.d.ts.map +1 -0
  122. package/dist/operations/service.js +336 -0
  123. package/dist/operations/service.js.map +1 -0
  124. package/dist/operations/tasks.d.ts +109 -0
  125. package/dist/operations/tasks.d.ts.map +1 -1
  126. package/dist/operations/tasks.js.map +1 -1
  127. package/dist/operations/validate.d.ts +1 -12
  128. package/dist/operations/validate.d.ts.map +1 -1
  129. package/dist/operations/validate.js +1 -1
  130. package/dist/playbook.d.ts +116 -0
  131. package/dist/playbook.d.ts.map +1 -1
  132. package/dist/release/plan.d.ts +5 -5
  133. package/dist/session.d.ts +11 -0
  134. package/dist/session.d.ts.map +1 -1
  135. package/dist/session.js.map +1 -1
  136. package/dist/templates/manifest.d.ts +1 -1
  137. package/dist/tools/agent-tools.d.ts +231 -0
  138. package/dist/tools/agent-tools.d.ts.map +1 -0
  139. package/dist/tools/agent-tools.js +25 -0
  140. package/dist/tools/agent-tools.js.map +1 -0
  141. package/dist/tools/atomic.d.ts +19 -0
  142. package/dist/tools/atomic.d.ts.map +1 -1
  143. package/dist/tools/atomic.js +17 -0
  144. package/dist/tools/atomic.js.map +1 -1
  145. package/dist/tools/index.d.ts +2 -0
  146. package/dist/tools/index.d.ts.map +1 -1
  147. package/dist/tools/skill-executor.d.ts +7 -0
  148. package/dist/tools/skill-executor.d.ts.map +1 -1
  149. package/dist/tools/web-tools.d.ts +217 -0
  150. package/dist/tools/web-tools.d.ts.map +1 -0
  151. package/dist/tools/web-tools.js +31 -0
  152. package/dist/tools/web-tools.js.map +1 -0
  153. package/dist/vault/service-provider.d.ts +343 -0
  154. package/dist/vault/service-provider.d.ts.map +1 -0
  155. package/dist/vault/service-provider.js +857 -0
  156. package/dist/vault/service-provider.js.map +1 -0
  157. package/dist/workgraph.d.ts +12 -12
  158. package/package.json +14 -2
  159. package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
  160. package/src/__tests__/operation-def.test.ts +7 -1
  161. package/src/__tests__/provider-def.test.ts +93 -0
  162. package/src/__tests__/sealed-credential.test.ts +100 -0
  163. package/src/__tests__/service-provider.test.ts +129 -0
  164. package/src/__tests__/skill-executor-contract.test.ts +3 -0
  165. package/src/acceptance-gate.ts +2 -3
  166. package/src/boundary.ts +70 -20
  167. package/src/conduit.ts +200 -0
  168. package/src/config/index.ts +35 -0
  169. package/src/config.ts +106 -1
  170. package/src/data-accessor.ts +22 -1
  171. package/src/dispatch/__tests__/tasks-gateway-crud-ops.test.ts +99 -0
  172. package/src/dispatch/identity.ts +25 -0
  173. package/src/dispatch/operation-def.ts +21 -0
  174. package/src/dispatch/operations-registry.ts +1083 -176
  175. package/src/index.ts +240 -25
  176. package/src/lease-ipc/__tests__/freeze.test.ts +342 -0
  177. package/src/lease-ipc/index.ts +75 -0
  178. package/src/lease-ipc/messages.ts +588 -0
  179. package/src/lease-ipc/version.ts +46 -0
  180. package/src/llm/catalog-schema.json +139 -0
  181. package/src/llm/catalog-schema.ts +184 -0
  182. package/src/llm/index.ts +29 -0
  183. package/src/llm/interfaces.ts +23 -0
  184. package/src/llm/oauth.ts +16 -2
  185. package/src/llm/onboarding.ts +131 -0
  186. package/src/llm/provider-def.ts +291 -0
  187. package/src/llm/sealed-credential.ts +166 -0
  188. package/src/llm/system-of-use.ts +503 -0
  189. package/src/llm/system-resolver.ts +91 -11
  190. package/src/operations/__tests__/ensures-schema-registry.test.ts +169 -0
  191. package/src/operations/admin.ts +144 -0
  192. package/src/operations/ensures-schema-registry.ts +260 -0
  193. package/src/operations/entities.ts +758 -0
  194. package/src/operations/llm.ts +120 -8
  195. package/src/operations/output-contracts-data.ts +264 -0
  196. package/src/operations/service.ts +360 -0
  197. package/src/operations/tasks.ts +119 -0
  198. package/src/operations/validate.ts +1 -14
  199. package/src/playbook.ts +117 -0
  200. package/src/session.ts +11 -0
  201. package/src/tools/agent-tools.ts +270 -0
  202. package/src/tools/atomic.ts +21 -0
  203. package/src/tools/index.ts +46 -0
  204. package/src/tools/skill-executor.ts +7 -0
  205. package/src/tools/web-tools.ts +247 -0
  206. package/src/vault/service-provider.ts +1137 -0
  207. package/dist/tessera.d.ts +0 -32
  208. package/dist/tessera.d.ts.map +0 -1
  209. package/dist/tessera.js +0 -11
  210. package/dist/tessera.js.map +0 -1
  211. package/dist/warp-chain.d.ts +0 -129
  212. package/dist/warp-chain.d.ts.map +0 -1
  213. package/dist/warp-chain.js +0 -13
  214. package/dist/warp-chain.js.map +0 -1
  215. package/src/tessera.ts +0 -35
  216. package/src/warp-chain.ts +0 -185
@@ -0,0 +1,588 @@
1
+ /**
2
+ * `lease-ipc` v1.1 — PARALLEL message contract (Zod schemas) for the
3
+ * DbWriterLease IPC surface (T11627 ST-1).
4
+ *
5
+ * This is the byte-for-byte TypeScript mirror of the Rust serde types in
6
+ * `crates/cleo-supervisor/src/lease_ipc.rs`. The wire format is newline-delimited
7
+ * JSON (NDJSON): one {@link LeaseIpcEnvelope} per line — identical framing to the
8
+ * frozen `supervisor-ipc` v1.0 envelope, only the version string
9
+ * ({@link LEASE_IPC_PROTOCOL_VERSION}) and the inner union differ.
10
+ *
11
+ * Wire-shape contract (snake_case keys — matches serde defaults):
12
+ *
13
+ * ```jsonc
14
+ * // request
15
+ * { "protocol_version": "1.1.0", "id": "abc", "direction": "request",
16
+ * "request": { "kind": "lease_acquire", "scope": "project", "lane": "tasks",
17
+ * "holder_id": "pid-42:tasks", "priority": 0, "ttl_ms": 30000,
18
+ * "reentrant": true } }
19
+ * // response
20
+ * { "protocol_version": "1.1.0", "id": "abc", "direction": "response",
21
+ * "response": { "kind": "lease_granted", "scope": "project", "lane": "tasks",
22
+ * "holder_id": "pid-42:tasks", "epoch": 7, "ttl_ms": 30000,
23
+ * "expires_at_ms": 1000030000 } }
24
+ * ```
25
+ *
26
+ * Staged delivery: every kind is *declared* so the protocol freeze is stable,
27
+ * but `rate_check` / `tool_grant` handlers are deferred (return
28
+ * `E_LEASE_UNIMPLEMENTED`) until a follow-up task. This module (ST-1) ships the
29
+ * protocol surface with **no consumer** — zero behavior change.
30
+ *
31
+ * @task T11627
32
+ * @packageDocumentation
33
+ */
34
+
35
+ import { z } from 'zod';
36
+
37
+ // ─── Shared value types ───────────────────────────────────────────────────────
38
+
39
+ /**
40
+ * The cleo.db scope a lease is arbitrated within. Mirrors `DbScope` in Rust.
41
+ *
42
+ * Under the dual-cleo.db split, a `project` lease lives inside the project's
43
+ * `cleo.db` and a `global` lease inside the global `cleo.db` — different files,
44
+ * so they never serialize against each other (AC2).
45
+ */
46
+ export const LeaseScopeSchema = z.enum(['project', 'global']);
47
+
48
+ /** The cleo.db scope a lease is arbitrated within (inferred). */
49
+ export type LeaseScope = z.infer<typeof LeaseScopeSchema>;
50
+
51
+ /**
52
+ * The write lane a lease arbitrates within a single scope file. Mirrors
53
+ * `LeaseLane` in Rust.
54
+ *
55
+ * - `tasks` — the primary task-chokepoint write lane.
56
+ * - `brain` — the BRAIN memory write lane (gated separately — AC4).
57
+ * - `bulk` — the bulk / bypass-writer lane (conduit, telemetry, nexus graph).
58
+ */
59
+ export const LeaseLaneSchema = z.enum(['tasks', 'brain', 'bulk']);
60
+
61
+ /** The write lane a lease arbitrates within a scope (inferred). */
62
+ export type LeaseLane = z.infer<typeof LeaseLaneSchema>;
63
+
64
+ // ─── Requests (client → arbiter) ──────────────────────────────────────────────
65
+
66
+ /**
67
+ * Acquire (or re-enter) the writer lease for a (scope, lane). Mirrors
68
+ * `LeaseAcquireReq`. `[v1 core]`
69
+ */
70
+ export const LeaseAcquireRequestSchema = z
71
+ .object({
72
+ /** Tag discriminating this request variant. */
73
+ kind: z.literal('lease_acquire'),
74
+ /** The cleo.db scope being arbitrated. */
75
+ scope: LeaseScopeSchema,
76
+ /** The write lane within the scope. */
77
+ lane: LeaseLaneSchema,
78
+ /** Process+lane holder identity. */
79
+ holder_id: z.string().min(1),
80
+ /** Advisory priority — lower acquires sooner. `0` = highest. */
81
+ priority: z.number().int().min(0).max(255),
82
+ /** Lease time-to-live in milliseconds. */
83
+ ttl_ms: z.number().int().nonnegative(),
84
+ /** When true, a same-holder acquire re-enters (refcount++) rather than queuing. */
85
+ reentrant: z.boolean(),
86
+ })
87
+ .strict();
88
+
89
+ /** Acquire request payload (inferred from {@link LeaseAcquireRequestSchema}). */
90
+ export type LeaseAcquireRequest = z.infer<typeof LeaseAcquireRequestSchema>;
91
+
92
+ /**
93
+ * Release the held writer lease. Mirrors `LeaseReleaseReq`. `[v1 core]`
94
+ */
95
+ export const LeaseReleaseRequestSchema = z
96
+ .object({
97
+ /** Tag discriminating this request variant. */
98
+ kind: z.literal('lease_release'),
99
+ /** The cleo.db scope being arbitrated. */
100
+ scope: LeaseScopeSchema,
101
+ /** The write lane within the scope. */
102
+ lane: LeaseLaneSchema,
103
+ /** Process+lane holder identity. */
104
+ holder_id: z.string().min(1),
105
+ /** The epoch fence the holder acquired — a stale epoch no-ops. */
106
+ epoch: z.number().int().nonnegative(),
107
+ })
108
+ .strict();
109
+
110
+ /** Release request payload (inferred from {@link LeaseReleaseRequestSchema}). */
111
+ export type LeaseReleaseRequest = z.infer<typeof LeaseReleaseRequestSchema>;
112
+
113
+ /**
114
+ * Heartbeat / renew the held lease's TTL. Mirrors `LeaseRenewReq`. `[v1 core]`
115
+ */
116
+ export const LeaseRenewRequestSchema = z
117
+ .object({
118
+ /** Tag discriminating this request variant. */
119
+ kind: z.literal('lease_renew'),
120
+ /** The cleo.db scope being arbitrated. */
121
+ scope: LeaseScopeSchema,
122
+ /** The write lane within the scope. */
123
+ lane: LeaseLaneSchema,
124
+ /** Process+lane holder identity. */
125
+ holder_id: z.string().min(1),
126
+ /** The epoch fence the holder acquired (epoch-guarded renew). */
127
+ epoch: z.number().int().nonnegative(),
128
+ })
129
+ .strict();
130
+
131
+ /** Renew request payload (inferred from {@link LeaseRenewRequestSchema}). */
132
+ export type LeaseRenewRequest = z.infer<typeof LeaseRenewRequestSchema>;
133
+
134
+ /**
135
+ * Check the per-scope write rate budget. Mirrors `RateCheckReq`.
136
+ * `[declared; handler deferred — returns E_LEASE_UNIMPLEMENTED]`
137
+ */
138
+ export const RateCheckRequestSchema = z
139
+ .object({
140
+ /** Tag discriminating this request variant. */
141
+ kind: z.literal('rate_check'),
142
+ /** The cleo.db scope being checked. */
143
+ scope: LeaseScopeSchema,
144
+ /** The write lane within the scope. */
145
+ lane: LeaseLaneSchema,
146
+ /** Estimated bytes the caller intends to write. */
147
+ est_bytes: z.number().int().nonnegative(),
148
+ })
149
+ .strict();
150
+
151
+ /** Rate-check request payload (inferred from {@link RateCheckRequestSchema}). */
152
+ export type RateCheckRequest = z.infer<typeof RateCheckRequestSchema>;
153
+
154
+ /**
155
+ * Request a tool-use grant. Mirrors `ToolGrantReq`.
156
+ * `[declared; handler deferred — returns E_LEASE_UNIMPLEMENTED]`
157
+ */
158
+ export const ToolGrantRequestSchema = z
159
+ .object({
160
+ /** Tag discriminating this request variant. */
161
+ kind: z.literal('tool_grant'),
162
+ /** The tool name being requested. */
163
+ tool: z.string().min(1),
164
+ /** The requesting holder identity. */
165
+ holder_id: z.string().min(1),
166
+ })
167
+ .strict();
168
+
169
+ /** Tool-grant request payload (inferred from {@link ToolGrantRequestSchema}). */
170
+ export type ToolGrantRequest = z.infer<typeof ToolGrantRequestSchema>;
171
+
172
+ /**
173
+ * The priority class of a `queue_admit` request (T11630). Mirrors the Rust
174
+ * `QueuePriorityClass` enum and `cleo_supervisor::llm_queue::PriorityClass`.
175
+ *
176
+ * `lead > worker > background` — a lead/orchestrator agent is never starved by a
177
+ * background consolidation (AC1).
178
+ */
179
+ export const QueuePriorityClassSchema = z.enum(['lead', 'worker', 'background']);
180
+
181
+ /** A `queue_admit` priority class (inferred from {@link QueuePriorityClassSchema}). */
182
+ export type QueuePriorityClass = z.infer<typeof QueuePriorityClassSchema>;
183
+
184
+ /**
185
+ * Admit (or defer) an outbound LLM call through the supervisor's priority
186
+ * scheduler + per-provider rate governor (T11630 · AC1-AC4). Mirrors
187
+ * `QueueAdmitReq`. `[wired]`
188
+ */
189
+ export const QueueAdmitRequestSchema = z
190
+ .object({
191
+ /** Tag discriminating this request variant. */
192
+ kind: z.literal('queue_admit'),
193
+ /** The LLM provider id the call targets (rate budget is per-provider). */
194
+ provider: z.string().min(1),
195
+ /** The caller's priority class (lead > worker > background). */
196
+ priority_class: QueuePriorityClassSchema,
197
+ /** The caller's estimate of the request's token cost (debited on admit). */
198
+ est_tokens: z.number().int().nonnegative(),
199
+ /** The child the call belongs to (in-flight tracking — the watchdog seam). */
200
+ child_id: z.string().min(1),
201
+ })
202
+ .strict();
203
+
204
+ /** Queue-admit request payload (inferred from {@link QueueAdmitRequestSchema}). */
205
+ export type QueueAdmitRequest = z.infer<typeof QueueAdmitRequestSchema>;
206
+
207
+ /**
208
+ * A liveness heartbeat from a managed worker (T11628). Mirrors
209
+ * `WorkerHeartbeatReq`. `[wired]`
210
+ *
211
+ * The worker sends this periodically (well inside the watchdog's NORMAL
212
+ * deadline) so the supervisor knows it is alive. `in_flight_llm` is the worker's
213
+ * OWN view of whether it is currently waiting on an LLM call: when true the
214
+ * watchdog grants the EXTENDED deadline even if the call never went through the
215
+ * `queue_admit` seam, so a slow-but-healthy long call is never false-killed
216
+ * (AC2 · RISK-7).
217
+ */
218
+ export const WorkerHeartbeatRequestSchema = z
219
+ .object({
220
+ /** Tag discriminating this request variant. */
221
+ kind: z.literal('worker_heartbeat'),
222
+ /** The logical id of the heartbeating child (matches the registry key). */
223
+ child_id: z.string().min(1),
224
+ /** The worker's own view of whether it is currently inside an LLM call. */
225
+ in_flight_llm: z.boolean(),
226
+ })
227
+ .strict();
228
+
229
+ /** Worker-heartbeat request payload (inferred from {@link WorkerHeartbeatRequestSchema}). */
230
+ export type WorkerHeartbeatRequest = z.infer<typeof WorkerHeartbeatRequestSchema>;
231
+
232
+ /**
233
+ * The discriminated union of all client → arbiter lease requests. The `kind`
234
+ * field selects the variant, matching the serde `#[serde(tag = "kind")]`
235
+ * tagging on the Rust `LeaseRequest` enum.
236
+ */
237
+ export const LeaseIpcRequestSchema = z.discriminatedUnion('kind', [
238
+ LeaseAcquireRequestSchema,
239
+ LeaseReleaseRequestSchema,
240
+ LeaseRenewRequestSchema,
241
+ RateCheckRequestSchema,
242
+ ToolGrantRequestSchema,
243
+ QueueAdmitRequestSchema,
244
+ WorkerHeartbeatRequestSchema,
245
+ ]);
246
+
247
+ /** Any lease IPC request (inferred from {@link LeaseIpcRequestSchema}). */
248
+ export type LeaseIpcRequest = z.infer<typeof LeaseIpcRequestSchema>;
249
+
250
+ // ─── Responses (arbiter → client) ─────────────────────────────────────────────
251
+
252
+ /**
253
+ * The lease was granted to the caller. Mirrors `LeaseGranted`.
254
+ */
255
+ export const LeaseGrantedResponseSchema = z
256
+ .object({
257
+ /** Tag discriminating this response variant. */
258
+ kind: z.literal('lease_granted'),
259
+ /** The granted cleo.db scope. */
260
+ scope: LeaseScopeSchema,
261
+ /** The granted write lane. */
262
+ lane: LeaseLaneSchema,
263
+ /** The holder the lease was granted to. */
264
+ holder_id: z.string().min(1),
265
+ /** The monotonic epoch fence assigned to this grant. */
266
+ epoch: z.number().int().nonnegative(),
267
+ /** The lease TTL in milliseconds. */
268
+ ttl_ms: z.number().int().nonnegative(),
269
+ /** Absolute expiry timestamp (epoch ms) for this grant. */
270
+ expires_at_ms: z.number().int().nonnegative(),
271
+ })
272
+ .strict();
273
+
274
+ /** Lease-granted response payload (inferred from {@link LeaseGrantedResponseSchema}). */
275
+ export type LeaseGrantedResponse = z.infer<typeof LeaseGrantedResponseSchema>;
276
+
277
+ /**
278
+ * The caller was placed in the per-scope FIFO+priority queue. Mirrors
279
+ * `LeaseQueued`.
280
+ */
281
+ export const LeaseQueuedResponseSchema = z
282
+ .object({
283
+ /** Tag discriminating this response variant. */
284
+ kind: z.literal('lease_queued'),
285
+ /** The queued cleo.db scope. */
286
+ scope: LeaseScopeSchema,
287
+ /** The queued write lane. */
288
+ lane: LeaseLaneSchema,
289
+ /** The monotonic ticket assigned for FIFO tiebreak. */
290
+ ticket: z.number().int().nonnegative(),
291
+ /** Number of waiters ahead of this one. */
292
+ ahead: z.number().int().nonnegative(),
293
+ })
294
+ .strict();
295
+
296
+ /** Lease-queued response payload (inferred from {@link LeaseQueuedResponseSchema}). */
297
+ export type LeaseQueuedResponse = z.infer<typeof LeaseQueuedResponseSchema>;
298
+
299
+ /**
300
+ * The acquire was denied. Mirrors `LeaseDenied`.
301
+ */
302
+ export const LeaseDeniedResponseSchema = z
303
+ .object({
304
+ /** Tag discriminating this response variant. */
305
+ kind: z.literal('lease_denied'),
306
+ /** The denied cleo.db scope. */
307
+ scope: LeaseScopeSchema,
308
+ /** Machine-readable denial code (e.g. `E_LEASE_UNAVAILABLE`). */
309
+ code: z.string().min(1),
310
+ /** Human-readable denial message. */
311
+ message: z.string(),
312
+ })
313
+ .strict();
314
+
315
+ /** Lease-denied response payload (inferred from {@link LeaseDeniedResponseSchema}). */
316
+ export type LeaseDeniedResponse = z.infer<typeof LeaseDeniedResponseSchema>;
317
+
318
+ /**
319
+ * Reply to a deferred `rate_check`. Mirrors `RateResult`.
320
+ */
321
+ export const RateResultResponseSchema = z
322
+ .object({
323
+ /** Tag discriminating this response variant. */
324
+ kind: z.literal('rate_result'),
325
+ /** The checked cleo.db scope. */
326
+ scope: LeaseScopeSchema,
327
+ /** Whether the write is within budget. */
328
+ ok: z.boolean(),
329
+ /** Suggested back-off in milliseconds when `ok` is false. */
330
+ retry_after_ms: z.number().int().nonnegative(),
331
+ /** Remaining token budget for the scope. */
332
+ tokens_remaining: z.number().int().nonnegative(),
333
+ })
334
+ .strict();
335
+
336
+ /** Rate-result response payload (inferred from {@link RateResultResponseSchema}). */
337
+ export type RateResultResponse = z.infer<typeof RateResultResponseSchema>;
338
+
339
+ /**
340
+ * Reply to a deferred `tool_grant`. Mirrors `ToolGranted`.
341
+ */
342
+ export const ToolGrantedResponseSchema = z
343
+ .object({
344
+ /** Tag discriminating this response variant. */
345
+ kind: z.literal('tool_granted'),
346
+ /** The granted tool name. */
347
+ tool: z.string().min(1),
348
+ /** The holder the tool grant was issued to. */
349
+ holder_id: z.string().min(1),
350
+ })
351
+ .strict();
352
+
353
+ /** Tool-granted response payload (inferred from {@link ToolGrantedResponseSchema}). */
354
+ export type ToolGrantedResponse = z.infer<typeof ToolGrantedResponseSchema>;
355
+
356
+ /**
357
+ * Unsolicited event: a held lease was revoked. Mirrors `LeaseRevoked`.
358
+ */
359
+ export const LeaseRevokedResponseSchema = z
360
+ .object({
361
+ /** Tag discriminating this response variant. */
362
+ kind: z.literal('lease_revoked'),
363
+ /** The revoked cleo.db scope. */
364
+ scope: LeaseScopeSchema,
365
+ /** The revoked write lane. */
366
+ lane: LeaseLaneSchema,
367
+ /** The holder whose lease was revoked. */
368
+ holder_id: z.string().min(1),
369
+ /** Human-readable reason for the revocation. */
370
+ reason: z.string(),
371
+ })
372
+ .strict();
373
+
374
+ /** Lease-revoked event payload (inferred from {@link LeaseRevokedResponseSchema}). */
375
+ export type LeaseRevokedResponse = z.infer<typeof LeaseRevokedResponseSchema>;
376
+
377
+ /**
378
+ * Unsolicited event: a lease holder was killed for being unresponsive. Mirrors
379
+ * `ChildKilled` carried by the `child_killed_unresponsive` response variant.
380
+ */
381
+ export const ChildKilledUnresponsiveResponseSchema = z
382
+ .object({
383
+ /** Tag discriminating this response variant. */
384
+ kind: z.literal('child_killed_unresponsive'),
385
+ /** Logical id of the killed child. */
386
+ child_id: z.string().min(1),
387
+ /** The holder identity the killed child held the lease as. */
388
+ holder_id: z.string().min(1),
389
+ /** The cleo.db scope the killed child held the lease in. */
390
+ scope: LeaseScopeSchema,
391
+ /** Human-readable reason for the kill. */
392
+ reason: z.string(),
393
+ })
394
+ .strict();
395
+
396
+ /** Child-killed event payload (inferred from {@link ChildKilledUnresponsiveResponseSchema}). */
397
+ export type ChildKilledUnresponsiveResponse = z.infer<typeof ChildKilledUnresponsiveResponseSchema>;
398
+
399
+ /**
400
+ * The disposition of a `queue_admit` request (T11630). Mirrors
401
+ * `QueueAdmitDisposition` in Rust — `admitted` (execute now) or `deferred`
402
+ * (back off `retry_after_ms` and re-request; AC4 — never a silent drop).
403
+ */
404
+ export const QueueAdmitDispositionSchema = z.enum(['admitted', 'deferred']);
405
+
406
+ /** A `queue_admit` disposition (inferred from {@link QueueAdmitDispositionSchema}). */
407
+ export type QueueAdmitDisposition = z.infer<typeof QueueAdmitDispositionSchema>;
408
+
409
+ /**
410
+ * Reply to a `queue_admit`: the LLM call was admitted or deferred (T11630).
411
+ * Mirrors `QueueAdmitResult`.
412
+ */
413
+ export const QueueAdmitResultResponseSchema = z
414
+ .object({
415
+ /** Tag discriminating this response variant. */
416
+ kind: z.literal('queue_admit_result'),
417
+ /** Whether the LLM call was admitted or deferred. */
418
+ disposition: QueueAdmitDispositionSchema,
419
+ /** Back-off in ms before re-requesting (0 when admitted). */
420
+ retry_after_ms: z.number().int().nonnegative(),
421
+ /** Remaining provider token budget after this decision. */
422
+ tokens_remaining: z.number().int().nonnegative(),
423
+ /** Number of higher/equal-priority waiters ahead (0 when admitted). */
424
+ queue_position: z.number().int().nonnegative(),
425
+ })
426
+ .strict();
427
+
428
+ /** Queue-admit result payload (inferred from {@link QueueAdmitResultResponseSchema}). */
429
+ export type QueueAdmitResultResponse = z.infer<typeof QueueAdmitResultResponseSchema>;
430
+
431
+ /**
432
+ * Acknowledge a `worker_heartbeat` (T11628). Mirrors `HeartbeatAck`.
433
+ *
434
+ * Deliberately carries only its `kind` — the ack's presence (correlated by id)
435
+ * is the signal that the watchdog recorded the beat and reset the child's
436
+ * deadline. Matches the Rust unit-struct wire shape `{ "kind": "heartbeat_ack" }`.
437
+ */
438
+ export const HeartbeatAckResponseSchema = z
439
+ .object({
440
+ /** Tag discriminating this response variant. */
441
+ kind: z.literal('heartbeat_ack'),
442
+ })
443
+ .strict();
444
+
445
+ /** Heartbeat-ack response payload (inferred from {@link HeartbeatAckResponseSchema}). */
446
+ export type HeartbeatAckResponse = z.infer<typeof HeartbeatAckResponseSchema>;
447
+
448
+ /**
449
+ * An error response correlated to a request. Mirrors the v1.0
450
+ * `crate::ipc::ErrorResult` shape reused by the Rust `LeaseResponse::Error`
451
+ * variant — error framing is shared across protocol versions.
452
+ */
453
+ export const LeaseErrorResponseSchema = z
454
+ .object({
455
+ /** Tag discriminating this response variant. */
456
+ kind: z.literal('error'),
457
+ /** Machine-readable error code (e.g. `E_LEASE_BAD_VERSION`, `E_LEASE_UNIMPLEMENTED`). */
458
+ code: z.string().min(1),
459
+ /** Human-readable error message. */
460
+ message: z.string(),
461
+ })
462
+ .strict();
463
+
464
+ /** Lease error response payload (inferred from {@link LeaseErrorResponseSchema}). */
465
+ export type LeaseErrorResponse = z.infer<typeof LeaseErrorResponseSchema>;
466
+
467
+ /**
468
+ * The discriminated union of all arbiter → client lease responses and events.
469
+ * The `kind` field selects the variant, matching the serde
470
+ * `#[serde(tag = "kind")]` tagging on the Rust `LeaseResponse` enum.
471
+ */
472
+ export const LeaseIpcResponseSchema = z.discriminatedUnion('kind', [
473
+ LeaseGrantedResponseSchema,
474
+ LeaseQueuedResponseSchema,
475
+ LeaseDeniedResponseSchema,
476
+ RateResultResponseSchema,
477
+ ToolGrantedResponseSchema,
478
+ LeaseRevokedResponseSchema,
479
+ ChildKilledUnresponsiveResponseSchema,
480
+ QueueAdmitResultResponseSchema,
481
+ HeartbeatAckResponseSchema,
482
+ LeaseErrorResponseSchema,
483
+ ]);
484
+
485
+ /** Any lease IPC response (inferred from {@link LeaseIpcResponseSchema}). */
486
+ export type LeaseIpcResponse = z.infer<typeof LeaseIpcResponseSchema>;
487
+
488
+ // ─── Envelope ──────────────────────────────────────────────────────────────────
489
+
490
+ /**
491
+ * A client → arbiter lease request envelope.
492
+ *
493
+ * The `direction` discriminator + flattened `request` payload mirror the serde
494
+ * `#[serde(tag = "direction")]` `LeasePayload::Request { request }` variant.
495
+ */
496
+ export const LeaseIpcRequestEnvelopeSchema = z
497
+ .object({
498
+ /** Parallel protocol version. */
499
+ protocol_version: z.string(),
500
+ /** Correlation id echoed back on the matching response. */
501
+ id: z.string().min(1),
502
+ /** Direction discriminator. */
503
+ direction: z.literal('request'),
504
+ /** The request body. */
505
+ request: LeaseIpcRequestSchema,
506
+ })
507
+ .strict();
508
+
509
+ /** Lease request envelope (inferred from {@link LeaseIpcRequestEnvelopeSchema}). */
510
+ export type LeaseIpcRequestEnvelope = z.infer<typeof LeaseIpcRequestEnvelopeSchema>;
511
+
512
+ /**
513
+ * An arbiter → client lease response/event envelope.
514
+ *
515
+ * The `direction` discriminator + flattened `response` payload mirror the serde
516
+ * `LeasePayload::Response { response }` variant.
517
+ */
518
+ export const LeaseIpcResponseEnvelopeSchema = z
519
+ .object({
520
+ /** Parallel protocol version. */
521
+ protocol_version: z.string(),
522
+ /** Correlation id echoed from the originating request (or a fresh id for events). */
523
+ id: z.string().min(1),
524
+ /** Direction discriminator. */
525
+ direction: z.literal('response'),
526
+ /** The response body. */
527
+ response: LeaseIpcResponseSchema,
528
+ })
529
+ .strict();
530
+
531
+ /** Lease response envelope (inferred from {@link LeaseIpcResponseEnvelopeSchema}). */
532
+ export type LeaseIpcResponseEnvelope = z.infer<typeof LeaseIpcResponseEnvelopeSchema>;
533
+
534
+ /**
535
+ * The top-level lease IPC envelope: a versioned, correlated wrapper that is
536
+ * either a request or a response, discriminated by `direction`. One envelope per
537
+ * NDJSON line. Mirrors the Rust `LeaseEnvelope`.
538
+ */
539
+ export const LeaseIpcEnvelopeSchema = z.discriminatedUnion('direction', [
540
+ LeaseIpcRequestEnvelopeSchema,
541
+ LeaseIpcResponseEnvelopeSchema,
542
+ ]);
543
+
544
+ /** Any lease IPC envelope (inferred from {@link LeaseIpcEnvelopeSchema}). */
545
+ export type LeaseIpcEnvelope = z.infer<typeof LeaseIpcEnvelopeSchema>;
546
+
547
+ // ─── Frozen message-set guard ──────────────────────────────────────────────────
548
+
549
+ /**
550
+ * The v1.1 request `kind` values, in declaration order. The schema-drift guard
551
+ * test pins this tuple; any addition/removal is a contract-breaking change
552
+ * requiring a coordinated dual (Rust + TS) edit.
553
+ */
554
+ export const LEASE_IPC_REQUEST_KINDS = [
555
+ 'lease_acquire',
556
+ 'lease_release',
557
+ 'lease_renew',
558
+ 'rate_check',
559
+ 'tool_grant',
560
+ 'queue_admit',
561
+ 'worker_heartbeat',
562
+ ] as const;
563
+
564
+ /**
565
+ * The v1.1 response `kind` values, in declaration order. The schema-drift guard
566
+ * test pins this tuple.
567
+ */
568
+ export const LEASE_IPC_RESPONSE_KINDS = [
569
+ 'lease_granted',
570
+ 'lease_queued',
571
+ 'lease_denied',
572
+ 'rate_result',
573
+ 'tool_granted',
574
+ 'lease_revoked',
575
+ 'child_killed_unresponsive',
576
+ 'queue_admit_result',
577
+ 'heartbeat_ack',
578
+ 'error',
579
+ ] as const;
580
+
581
+ /**
582
+ * The complete v1.1 message kind set (requests + responses), used by the drift
583
+ * guard on both the TS and Rust sides.
584
+ */
585
+ export const LEASE_IPC_MESSAGE_KINDS = [
586
+ ...LEASE_IPC_REQUEST_KINDS,
587
+ ...LEASE_IPC_RESPONSE_KINDS,
588
+ ] as const;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * PARALLEL protocol version for the `lease-ipc` v1.1 contract (T11627 ST-1).
3
+ *
4
+ * The Rust arbiter (`crates/cleo-supervisor/src/lease_ipc.rs`) and this
5
+ * TypeScript contract MUST agree on this value. It runs **in parallel** to the
6
+ * byte-frozen `supervisor-ipc` v1.0 contract: the two are distinguished on the
7
+ * wire purely by this version string, so a single accept loop can route
8
+ * `'1.0.0'` → the v1.0 union and `'1.1.0'` → the lease union. Bump only via a
9
+ * coordinated dual (Rust + TS) edit, never edit this value in place.
10
+ *
11
+ * @see {@link LEASE_IPC_MESSAGE_KINDS} for the v1.1 message set.
12
+ * @task T11627
13
+ * @packageDocumentation
14
+ */
15
+
16
+ /**
17
+ * The `lease-ipc` v1.1 protocol version string.
18
+ *
19
+ * Mirrors `cleo_supervisor::lease_ipc::LEASE_IPC_PROTOCOL_VERSION` on the Rust
20
+ * side. Both the Rust schema-drift guard (`lease_ipc::tests`) and the TS drift
21
+ * test (`__tests__/freeze.test.ts`) pin this exact value.
22
+ */
23
+ export const LEASE_IPC_PROTOCOL_VERSION = '1.1.0' as const;
24
+
25
+ /**
26
+ * Whether the given version string is the frozen `lease-ipc` v1.1 wire version.
27
+ *
28
+ * Used by an accept-loop version router to confirm a frame is a lease-protocol
29
+ * frame before dispatching it through the {@link LEASE_IPC_PROTOCOL_VERSION}
30
+ * union (rather than the v1.0 supervisor-ipc union).
31
+ *
32
+ * @param version - The `protocol_version` field read off an inbound envelope.
33
+ * @returns `true` iff `version` equals {@link LEASE_IPC_PROTOCOL_VERSION}.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * if (isFrozenLeaseIpcVersion(env.protocol_version)) {
38
+ * // dispatch through LeaseIpcEnvelopeSchema
39
+ * }
40
+ * ```
41
+ */
42
+ export function isFrozenLeaseIpcVersion(
43
+ version: string,
44
+ ): version is typeof LEASE_IPC_PROTOCOL_VERSION {
45
+ return version === LEASE_IPC_PROTOCOL_VERSION;
46
+ }