@namzu/sandbox 14.0.0 → 15.0.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.
Files changed (99) hide show
  1. package/CHANGELOG.md +838 -0
  2. package/README.md +310 -14
  3. package/dist/backends/aci-standby-pool/index.d.ts.map +1 -1
  4. package/dist/backends/aci-standby-pool/index.js +13 -1
  5. package/dist/backends/aci-standby-pool/index.js.map +1 -1
  6. package/dist/backends/docker/index.d.ts.map +1 -1
  7. package/dist/backends/docker/index.js +19 -1
  8. package/dist/backends/docker/index.js.map +1 -1
  9. package/dist/backends/firecracker/index.d.ts.map +1 -1
  10. package/dist/backends/firecracker/index.js +12 -2
  11. package/dist/backends/firecracker/index.js.map +1 -1
  12. package/dist/backends/firecracker/protocol.d.ts +459 -8
  13. package/dist/backends/firecracker/protocol.d.ts.map +1 -1
  14. package/dist/backends/firecracker/protocol.js +136 -0
  15. package/dist/backends/firecracker/protocol.js.map +1 -1
  16. package/dist/backends/firecracker/transport.d.ts +539 -6
  17. package/dist/backends/firecracker/transport.d.ts.map +1 -1
  18. package/dist/backends/firecracker/transport.js +1171 -24
  19. package/dist/backends/firecracker/transport.js.map +1 -1
  20. package/dist/backends/kubernetes/egress-policy.d.ts +1088 -11
  21. package/dist/backends/kubernetes/egress-policy.d.ts.map +1 -1
  22. package/dist/backends/kubernetes/egress-policy.js +2173 -29
  23. package/dist/backends/kubernetes/egress-policy.js.map +1 -1
  24. package/dist/backends/kubernetes/identity.d.ts +193 -0
  25. package/dist/backends/kubernetes/identity.d.ts.map +1 -0
  26. package/dist/backends/kubernetes/identity.js +147 -0
  27. package/dist/backends/kubernetes/identity.js.map +1 -0
  28. package/dist/backends/kubernetes/index.d.ts +678 -33
  29. package/dist/backends/kubernetes/index.d.ts.map +1 -1
  30. package/dist/backends/kubernetes/index.js +1180 -95
  31. package/dist/backends/kubernetes/index.js.map +1 -1
  32. package/dist/backends/kubernetes/ingress-policy.d.ts +375 -0
  33. package/dist/backends/kubernetes/ingress-policy.d.ts.map +1 -0
  34. package/dist/backends/kubernetes/ingress-policy.js +1050 -0
  35. package/dist/backends/kubernetes/ingress-policy.js.map +1 -0
  36. package/dist/backends/kubernetes/k8s-client.d.ts +213 -4
  37. package/dist/backends/kubernetes/k8s-client.d.ts.map +1 -1
  38. package/dist/backends/kubernetes/k8s-client.js +359 -52
  39. package/dist/backends/kubernetes/k8s-client.js.map +1 -1
  40. package/dist/backends/kubernetes/lease.d.ts +40 -14
  41. package/dist/backends/kubernetes/lease.d.ts.map +1 -1
  42. package/dist/backends/kubernetes/lease.js +68 -18
  43. package/dist/backends/kubernetes/lease.js.map +1 -1
  44. package/dist/backends/kubernetes/objects.d.ts +423 -3
  45. package/dist/backends/kubernetes/objects.d.ts.map +1 -1
  46. package/dist/backends/kubernetes/objects.js +364 -2
  47. package/dist/backends/kubernetes/objects.js.map +1 -1
  48. package/dist/backends/kubernetes/per-sandbox-policy.d.ts +219 -0
  49. package/dist/backends/kubernetes/per-sandbox-policy.d.ts.map +1 -0
  50. package/dist/backends/kubernetes/per-sandbox-policy.js +407 -0
  51. package/dist/backends/kubernetes/per-sandbox-policy.js.map +1 -0
  52. package/dist/backends/kubernetes/rbac.d.ts +153 -0
  53. package/dist/backends/kubernetes/rbac.d.ts.map +1 -0
  54. package/dist/backends/kubernetes/rbac.js +177 -0
  55. package/dist/backends/kubernetes/rbac.js.map +1 -0
  56. package/dist/backends/kubernetes/sandbox.d.ts +81 -14
  57. package/dist/backends/kubernetes/sandbox.d.ts.map +1 -1
  58. package/dist/backends/kubernetes/sandbox.js +149 -15
  59. package/dist/backends/kubernetes/sandbox.js.map +1 -1
  60. package/dist/backends/kubernetes/transport.d.ts +935 -9
  61. package/dist/backends/kubernetes/transport.d.ts.map +1 -1
  62. package/dist/backends/kubernetes/transport.js +1958 -62
  63. package/dist/backends/kubernetes/transport.js.map +1 -1
  64. package/dist/backends/kubernetes/workspace.d.ts +1149 -18
  65. package/dist/backends/kubernetes/workspace.d.ts.map +1 -1
  66. package/dist/backends/kubernetes/workspace.js +2825 -186
  67. package/dist/backends/kubernetes/workspace.js.map +1 -1
  68. package/dist/backends/remote-execution-controller.d.ts +14 -0
  69. package/dist/backends/remote-execution-controller.d.ts.map +1 -1
  70. package/dist/backends/remote-execution-controller.js.map +1 -1
  71. package/dist/index.d.ts +231 -13
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +247 -5
  74. package/dist/index.js.map +1 -1
  75. package/dist/testing/sandbox-conformance.d.ts +39 -5
  76. package/dist/testing/sandbox-conformance.d.ts.map +1 -1
  77. package/dist/testing/sandbox-conformance.js +436 -5
  78. package/dist/testing/sandbox-conformance.js.map +1 -1
  79. package/package.json +3 -3
  80. package/src/backends/aci-standby-pool/index.ts +16 -1
  81. package/src/backends/docker/index.ts +22 -1
  82. package/src/backends/firecracker/index.ts +14 -2
  83. package/src/backends/firecracker/protocol.ts +514 -6
  84. package/src/backends/firecracker/transport.ts +1492 -40
  85. package/src/backends/kubernetes/egress-policy.ts +3064 -53
  86. package/src/backends/kubernetes/identity.ts +261 -0
  87. package/src/backends/kubernetes/index.ts +1785 -127
  88. package/src/backends/kubernetes/ingress-policy.ts +1344 -0
  89. package/src/backends/kubernetes/k8s-client.ts +444 -54
  90. package/src/backends/kubernetes/lease.ts +75 -19
  91. package/src/backends/kubernetes/objects.ts +626 -6
  92. package/src/backends/kubernetes/per-sandbox-policy.ts +542 -0
  93. package/src/backends/kubernetes/rbac.ts +192 -0
  94. package/src/backends/kubernetes/sandbox.ts +218 -20
  95. package/src/backends/kubernetes/transport.ts +2733 -124
  96. package/src/backends/kubernetes/workspace.ts +4476 -222
  97. package/src/backends/remote-execution-controller.ts +14 -0
  98. package/src/index.ts +595 -14
  99. package/src/testing/sandbox-conformance.ts +540 -5
@@ -52,21 +52,42 @@ export interface ExecRequest {
52
52
  readonly stdin?: string;
53
53
  readonly timeoutMs?: number;
54
54
  readonly maxOutputBytes?: number;
55
+ /**
56
+ * Ask the guest to keep this command's output in its retained log, so a
57
+ * host that loses the data connection can reattach by execution id and
58
+ * read on from the offset it reached.
59
+ *
60
+ * Requires `executionId` — a log nobody can name is a log nobody can
61
+ * attach to — and requires the guest to advertise `execution-attach` in
62
+ * its `healthz` features. Omitted on every ordinary exec, which is why
63
+ * the default wire request is byte-for-byte what it has always been.
64
+ */
65
+ readonly retainOutput?: boolean;
55
66
  }
56
67
  /**
57
68
  * One NDJSON event the agent emits while streaming an `/execute`. The
58
69
  * exact union the HTTP worker writes via `writeEvent`:
59
70
  * { type: 'stdout_delta', data }
60
71
  * { type: 'stderr_delta', data }
72
+ *
73
+ * A delta of an execution the guest was asked to RETAIN also carries
74
+ * `offset` and `nextOffset`: the bytes the chunk occupies in that
75
+ * execution's retained log. They are additive, ignored by every consumer
76
+ * that does not reattach, and they are the only correct source for a
77
+ * reattach cursor — see {@link parseExecEvent}.
61
78
  * { type: 'result', exitCode, timedOut, durationMs, stdoutTruncated?, stderrTruncated? }
62
79
  * { type: 'error', error }
63
80
  */
64
81
  export type ExecEvent = {
65
82
  readonly type: 'stdout_delta';
66
83
  readonly data: string;
84
+ readonly offset?: number;
85
+ readonly nextOffset?: number;
67
86
  } | {
68
87
  readonly type: 'stderr_delta';
69
88
  readonly data: string;
89
+ readonly offset?: number;
90
+ readonly nextOffset?: number;
70
91
  } | {
71
92
  readonly type: 'result';
72
93
  readonly exitCode: number;
@@ -79,23 +100,140 @@ export type ExecEvent = {
79
100
  readonly type: 'error';
80
101
  readonly error: string;
81
102
  };
103
+ /**
104
+ * One slice of a `write-file` body, for a body too large to cross the wire
105
+ * in a single frame.
106
+ *
107
+ * ADDITIVE, and deliberately so: the guest protocol version is unchanged,
108
+ * an agent that predates this field ignores it, and a host only ever sends
109
+ * it to an agent that advertised {@link WRITE_FILE_PARTS_FEATURE} in its
110
+ * `healthz` reply. The sequence writes a temporary sibling of the target
111
+ * (`WriteFileRequest.path` names the TEMP file while `part` is present, so
112
+ * an agent that dropped the field would overwrite the temp file rather
113
+ * than the target) and finishes with an atomic rename onto `renameTo`.
114
+ */
115
+ export interface WriteFilePart {
116
+ /**
117
+ * Byte offset in the temp file this slice starts at. `0` creates or
118
+ * truncates it; any other value must equal the temp file's CURRENT
119
+ * size, so a lost, duplicated or reordered part is refused rather
120
+ * than silently producing a corrupt file.
121
+ */
122
+ readonly offset?: number;
123
+ /** Last slice: rename the temp file onto {@link renameTo} once written. */
124
+ readonly final?: boolean;
125
+ /** The real target, required when {@link final} is true. */
126
+ readonly renameTo?: string;
127
+ /**
128
+ * Remove the temp file named by `path` and write nothing — the
129
+ * best-effort cleanup a host runs when a part sequence is abandoned.
130
+ * `content` is ignored.
131
+ */
132
+ readonly discard?: boolean;
133
+ }
82
134
  /** `/write-file` request body. `content` is base64. */
83
135
  export interface WriteFileRequest {
84
136
  readonly path: string;
85
137
  readonly content: string;
86
138
  readonly encoding: 'base64';
139
+ /** Present only for a chunked write; see {@link WriteFilePart}. */
140
+ readonly part?: WriteFilePart;
87
141
  }
88
142
  /** `/write-file` success response. */
89
143
  export interface WriteFileResponse {
90
144
  readonly ok: boolean;
91
145
  readonly bytesWritten?: number;
146
+ /** Total size of the temp file after this part, for a chunked write. */
147
+ readonly sizeBytes?: number;
92
148
  readonly error?: string;
93
149
  }
94
- /** `/read-file` request body. */
150
+ /**
151
+ * The `healthz` feature string an agent advertises when it implements
152
+ * {@link WriteFilePart}. A host that does not see it in `features` keeps
153
+ * to the single-frame write and its named too-large error.
154
+ */
155
+ export declare const WRITE_FILE_PARTS_FEATURE = "write-file-parts";
156
+ /**
157
+ * The `healthz` feature string an agent advertises when it accepts a
158
+ * caller-chosen `executionId`, an `execute` carrying `retainOutput`, and
159
+ * the `attach-execution` op that replays a retained execution's output by
160
+ * byte offset.
161
+ *
162
+ * A host asking for a detachable command against a guest that does not
163
+ * advertise it is refused BEFORE the command is admitted, rather than
164
+ * starting one whose output nothing keeps.
165
+ */
166
+ export declare const EXECUTION_ATTACH_FEATURE = "execution-attach";
167
+ /**
168
+ * `/read-file` request body.
169
+ *
170
+ * `offset`/`length` are ADDITIVE and gated exactly as {@link WriteFilePart}
171
+ * is: a host sends them only to an agent that advertised
172
+ * {@link READ_FILE_STREAM_FEATURE} in its `healthz` reply, because an agent
173
+ * that predates them ignores both and answers with the WHOLE file — which
174
+ * the caller would read as its slice. Omitting both is the whole-file read
175
+ * this op has always served, byte for byte.
176
+ */
95
177
  export interface ReadFileRequest {
96
178
  readonly path: string;
97
179
  readonly encoding: 'base64';
180
+ /** First byte of the slice. Defaults to 0 when only `length` is given. */
181
+ readonly offset?: number;
182
+ /**
183
+ * How many bytes to answer with. Defaults to the rest of the file, and
184
+ * is REFUSED rather than shortened above the guest's per-frame range
185
+ * ceiling (`NAMZU_AGENT_READ_FILE_RANGE_BYTES`, 1 MiB by default) — a
186
+ * whole file goes through {@link ReadFileStreamRequest} instead.
187
+ */
188
+ readonly length?: number;
98
189
  }
190
+ /**
191
+ * `read-file-stream` request body — one file as an ordered sequence of
192
+ * frames rather than one reply.
193
+ *
194
+ * `offset`/`length` are accepted and deliberately NOT capped: this op is
195
+ * where {@link ReadFileRequest}'s range ceiling sends a caller who wants
196
+ * more than one frame's worth.
197
+ */
198
+ export interface ReadFileStreamRequest {
199
+ readonly path: string;
200
+ readonly offset?: number;
201
+ readonly length?: number;
202
+ }
203
+ /**
204
+ * Guest → host frames for one `read-file-stream`, in order: exactly one
205
+ * `meta`, zero or more `data`, then one `end` — or a single `error`
206
+ * instead of any of them — followed by the zero-length terminator.
207
+ *
208
+ * `data` is base64 for the same reason every other payload on this wire
209
+ * is: the frame body is UTF-8 JSON, which cannot carry arbitrary bytes.
210
+ */
211
+ export type ReadFileStreamEvent = {
212
+ readonly type: 'meta';
213
+ /** The WHOLE file's size, never the slice's — how a caller knows where it ends. */
214
+ readonly sizeBytes: number;
215
+ readonly offset: number;
216
+ /** What this stream intends to send, after clamping to EOF. */
217
+ readonly length: number;
218
+ } | {
219
+ readonly type: 'data';
220
+ readonly data: string;
221
+ } | {
222
+ readonly type: 'end';
223
+ readonly bytesSent: number;
224
+ } | {
225
+ readonly type: 'error';
226
+ readonly error: string;
227
+ };
228
+ /**
229
+ * The `healthz` feature string an agent advertises when `read-file`
230
+ * honours {@link ReadFileRequest.offset}/`length` AND the
231
+ * `read-file-stream` op exists. ONE string for both halves because they
232
+ * ship together in `agent/agent.cjs` and no guest can have one without the
233
+ * other; a host that does not see it sends neither shape and keeps to the
234
+ * single whole-file reply.
235
+ */
236
+ export declare const READ_FILE_STREAM_FEATURE = "read-file-stream";
99
237
  /** Initial request for one interactive terminal process in the guest. */
100
238
  export interface TerminalOpenRequest {
101
239
  readonly command?: string;
@@ -104,6 +242,22 @@ export interface TerminalOpenRequest {
104
242
  readonly env?: Record<string, string>;
105
243
  readonly cols: number;
106
244
  readonly rows: number;
245
+ /** See {@link StreamHeartbeat}. Absent → no heartbeat on this stream. */
246
+ readonly heartbeatMs?: number;
247
+ /**
248
+ * Name this terminal so it can be found again. Both fields are ADDITIVE
249
+ * and both are required together: a guest that predates them ignores
250
+ * them and serves the connection-bound terminal it always served, which
251
+ * is why a host only ever sends them to one advertising
252
+ * {@link SESSIONS_FEATURE}.
253
+ *
254
+ * With them, the PTY belongs to the guest's session registry rather than
255
+ * to this connection: output is read into a retained log whether or not
256
+ * anybody is attached, and closing the connection detaches instead of
257
+ * killing.
258
+ */
259
+ readonly sessionId?: string;
260
+ readonly persistent?: boolean;
107
261
  }
108
262
  /** Host → guest messages after the terminal stream reports ready. */
109
263
  export type TerminalInputEvent = {
@@ -116,24 +270,234 @@ export type TerminalInputEvent = {
116
270
  } | {
117
271
  readonly type: 'kill';
118
272
  readonly signal?: string;
119
- };
273
+ } | StreamHeartbeat;
120
274
  /** Guest → host events carried for the lifetime of the terminal stream. */
121
- export type TerminalOutputEvent = {
122
- readonly type: 'ready';
123
- } | {
275
+ export type TerminalOutputEvent = TerminalReadyEvent | {
124
276
  readonly type: 'data';
125
277
  readonly data: string;
278
+ /** Only on a session stream: where this chunk sits in the retained log. */
279
+ readonly stream?: SessionStreamName;
280
+ readonly offset?: number;
281
+ readonly nextOffset?: number;
126
282
  } | {
127
283
  readonly type: 'exit';
128
284
  readonly exitCode: number;
129
285
  readonly signal?: number;
130
- } | {
286
+ readonly nextOffset?: number;
287
+ } | SessionDetachedEvent | {
131
288
  readonly type: 'error';
132
289
  readonly error: string;
133
- };
290
+ } | StreamHeartbeat;
291
+ /**
292
+ * The opening frame of a terminal stream, and the one place the session ops
293
+ * add to it.
294
+ *
295
+ * Every session field is optional because a connection-bound terminal sends
296
+ * none of them, and a guest that predates the registry sends none either.
297
+ */
298
+ export interface TerminalReadyEvent {
299
+ readonly type: 'ready';
300
+ readonly heartbeatMs?: number;
301
+ /**
302
+ * The guest agent PROCESS this stream reached — see
303
+ * {@link GUEST_BOOT_ID_FEATURE}. Absent from a guest that predates it, so
304
+ * nothing may require it.
305
+ */
306
+ readonly guestBootId?: string;
307
+ readonly sessionId?: string;
308
+ readonly kind?: SessionKind;
309
+ readonly state?: SessionState;
310
+ /** Where the replay this stream is about to send begins. */
311
+ readonly fromOffset?: number;
312
+ /** Bytes evicted between what the reader asked for and what survived. */
313
+ readonly droppedBytes?: number;
314
+ /** One past the newest byte the guest had when the stream opened. */
315
+ readonly nextOffset?: number;
316
+ readonly exitCode?: number;
317
+ readonly signal?: number;
318
+ }
319
+ /**
320
+ * The `healthz` feature string an agent advertises when it keeps a session
321
+ * registry: `terminal` with `{ sessionId, persistent: true }`, plus the
322
+ * `attach-session`, `start-detached`, `list-sessions` and `kill-session`
323
+ * ops.
324
+ *
325
+ * A host asking for any of them against a guest that does not advertise it
326
+ * is refused by name and never falls back to a connection-bound terminal: a
327
+ * caller that asked for a session is about to rely on coming back to it, and
328
+ * handing it one that dies with the socket would keep nothing and tell
329
+ * nobody.
330
+ */
331
+ export declare const SESSIONS_FEATURE = "sessions";
332
+ /**
333
+ * `healthz.features` entry: every authenticated reply and every stream
334
+ * `ready` frame carries a `guestBootId` naming the agent PROCESS that
335
+ * answered.
336
+ *
337
+ * The field is optional on every shape that carries it and a host must treat
338
+ * an absent one as "this guest cannot tell me" rather than as a change — an
339
+ * image built before this existed answers exactly as it always did. The
340
+ * feature string is here for the one host that wants to REQUIRE the evidence
341
+ * (a Kubernetes workspace deciding whether a command's guest is still the
342
+ * one it started on) and needs to know before it relies on it.
343
+ */
344
+ export declare const GUEST_BOOT_ID_FEATURE = "guest-boot-id";
345
+ /**
346
+ * The identity fields an authenticated reply may carry, and the whole of
347
+ * what an observer of one is allowed to read.
348
+ *
349
+ * Deliberately not the reply itself: an observer exists to follow the GUEST,
350
+ * and widening it to the payload would make every reply's content reachable
351
+ * from a hook whose job is a single opaque id.
352
+ */
353
+ export interface GuestReplyIdentity {
354
+ readonly guestBootId?: string;
355
+ }
356
+ /** A PTY, or a program started with no terminal at all. */
357
+ export type SessionKind = 'terminal' | 'detached';
358
+ export type SessionState = 'running' | 'exited';
359
+ /** Which of the two streams a retained chunk came from. */
360
+ export type SessionStreamName = 'stdout' | 'stderr';
361
+ /** Why an attachment ended without the program exiting. */
362
+ export type SessionDetachReason = 'superseded' | 'slow_reader';
363
+ /**
364
+ * Sent to the attachment a session is taking away from it. It is never an
365
+ * exit: the program is still running, and the reason says who took it.
366
+ */
367
+ export interface SessionDetachedEvent {
368
+ readonly type: 'detached';
369
+ readonly reason: SessionDetachReason;
370
+ }
371
+ /** Read one session's retained output, and optionally follow it live. */
372
+ export interface AttachSessionRequest {
373
+ readonly sessionId: string;
374
+ /** Byte offset to resume from. Default 0 — the whole retained log. */
375
+ readonly fromOffset?: number;
376
+ /**
377
+ * `false` replays what is retained and ends. Default `true`: stay
378
+ * attached, and — for a terminal session — accept input and resize.
379
+ */
380
+ readonly follow?: boolean;
381
+ /** Resize the PTY on attach, for a terminal whose new reader has its own window. */
382
+ readonly cols?: number;
383
+ readonly rows?: number;
384
+ /** See {@link StreamHeartbeat}. Absent → no heartbeat on this stream. */
385
+ readonly heartbeatMs?: number;
386
+ }
387
+ /** Start a program with no terminal, which nothing but a kill ends. */
388
+ export interface StartDetachedRequest {
389
+ readonly sessionId: string;
390
+ readonly command: string;
391
+ readonly args?: readonly string[];
392
+ readonly cwd?: string;
393
+ readonly env?: Record<string, string>;
394
+ }
395
+ /** End one session and everything still in it. */
396
+ export interface KillSessionRequest {
397
+ readonly sessionId: string;
398
+ /** `SIGTERM`, `SIGKILL`, `SIGINT` or `SIGHUP`. Default `SIGKILL`. */
399
+ readonly signal?: string;
400
+ }
401
+ /**
402
+ * The `healthz` feature string an agent advertises when it implements the
403
+ * `quiesce` op: stop every process this guest is running — including ones
404
+ * no session and no execution owns — and go on serving `execute`,
405
+ * `read-file` and `write-file` afterwards.
406
+ *
407
+ * Gated exactly like {@link SESSIONS_FEATURE}: a host sends the op only to
408
+ * a guest that advertised it, because an agent that predates it answers
409
+ * `unknown_op: quiesce` and a host that read that as "nothing was running"
410
+ * would take its capture over a disk somebody is still writing to.
411
+ */
412
+ export declare const QUIESCE_FEATURE = "quiesce";
413
+ /** Stop everything. `graceMs` bounds ONE round's SIGTERM window. */
414
+ export interface QuiesceRequest {
415
+ /**
416
+ * How long a round waits after `SIGTERM` before it escalates to
417
+ * `SIGKILL`. The guest refuses a value at or above its own
418
+ * cancel-confirmation timeout (5000ms by default) and defaults to
419
+ * 1000ms. It is NOT the pod's `terminationGracePeriodSeconds`.
420
+ */
421
+ readonly graceMs?: number;
422
+ }
423
+ /**
424
+ * How wide the guest's scan was allowed to be — reported, so a narrowed
425
+ * scan is never silently weaker than the one the host asked for.
426
+ *
427
+ * - `pid-namespace` — every process in the guest's PID namespace but its
428
+ * init and the agent. What a shipped pod does.
429
+ * - `owned-sessions` — only the kernel sessions the guest's own registries
430
+ * own, which an agent that is not the init of its own PID namespace
431
+ * narrows itself to. It can miss a program that moved into a session of
432
+ * its own.
433
+ */
434
+ export type QuiesceScope = 'pid-namespace' | 'owned-sessions';
435
+ /** One process a quiesce stopped, and the signal that stopped it. */
436
+ export interface QuiescedProcess {
437
+ readonly pid: number;
438
+ /**
439
+ * The kernel's short name for the executable (`/proc/<pid>/stat`), not
440
+ * the command line: this travels to the host, and a command line
441
+ * carries the workload's own arguments.
442
+ */
443
+ readonly command: string;
444
+ readonly signal: 'SIGTERM' | 'SIGKILL';
445
+ }
446
+ /** What a successful `quiesce` answers with. */
447
+ export interface QuiesceReply {
448
+ readonly ok: true;
449
+ readonly stopped: readonly QuiescedProcess[];
450
+ readonly scope: QuiesceScope;
451
+ /** The window each round actually used, after the guest's own clamp. */
452
+ readonly graceMs: number;
453
+ /** Scan-and-signal passes performed. `0` means nothing was running. */
454
+ readonly rounds: number;
455
+ }
456
+ /**
457
+ * The `healthz` feature string an agent advertises when it implements the
458
+ * `flush` op: run `syncfs(2)` over the workspace mount and answer only once
459
+ * it has returned.
460
+ *
461
+ * Gated exactly like {@link QUIESCE_FEATURE}, and for a sharper reason than
462
+ * any other feature in this file: an agent that predates the op answers
463
+ * `unknown_op: flush`, and a host that read that as "the disk is flushed"
464
+ * would take the pod away over pages that never reached the device. So the
465
+ * op is sent only to a guest that named it, and a guest that did not is
466
+ * reported as one that cannot flush rather than one that had nothing to.
467
+ *
468
+ * An agent that HAS the op advertises it only when it can actually perform
469
+ * one: the flush runs a program, and an image that stripped it has the code
470
+ * and nothing to run. Such a guest also answers `flush_unsupported` to an op
471
+ * sent anyway, which a host reads exactly as the missing string — because
472
+ * the alternative, an unconfirmed flush, is the shape that means "the disk
473
+ * may be missing writes" and would refuse that image's every suspend
474
+ * forever.
475
+ */
476
+ export declare const FLUSH_FEATURE = "flush";
477
+ /** Flush the workspace filesystem. */
478
+ export interface FlushRequest {
479
+ /**
480
+ * How long the guest may spend on the `syncfs` before it reports the
481
+ * flush unconfirmed. The guest defaults to 10000ms
482
+ * (`NAMZU_AGENT_FLUSH_TIMEOUT_MS`). It is NOT the pod's
483
+ * `terminationGracePeriodSeconds`, which has to cover this and the
484
+ * guest's own termination drain together.
485
+ */
486
+ readonly timeoutMs?: number;
487
+ }
488
+ /** What a successful `flush` answers with. */
489
+ export interface FlushReply {
490
+ readonly ok: true;
491
+ /** How long the `syncfs` itself took, as the guest measured it. */
492
+ readonly durationMs: number;
493
+ /** The mount the guest flushed — its workspace root. */
494
+ readonly workspace: string;
495
+ }
134
496
  export interface TcpConnectRequest {
135
497
  readonly host: '127.0.0.1' | '::1';
136
498
  readonly port: number;
499
+ /** See {@link StreamHeartbeat}. Absent → no heartbeat on this stream. */
500
+ readonly heartbeatMs?: number;
137
501
  }
138
502
  export type TcpInputEvent = {
139
503
  readonly type: 'data';
@@ -142,9 +506,11 @@ export type TcpInputEvent = {
142
506
  readonly type: 'end';
143
507
  } | {
144
508
  readonly type: 'destroy';
145
- };
509
+ } | StreamHeartbeat;
146
510
  export type TcpOutputEvent = {
147
511
  readonly type: 'ready';
512
+ readonly heartbeatMs?: number;
513
+ readonly guestBootId?: string;
148
514
  } | {
149
515
  readonly type: 'data';
150
516
  readonly data: string;
@@ -153,14 +519,88 @@ export type TcpOutputEvent = {
153
519
  } | {
154
520
  readonly type: 'error';
155
521
  readonly error: string;
522
+ } | StreamHeartbeat;
523
+ /**
524
+ * The one frame either side of an open `terminal` or `tcp-connect` stream
525
+ * may send to say it is still there.
526
+ *
527
+ * Once a stream reports `ready` the transport clears its read-idle timer,
528
+ * correctly: an interactive shell may sit silent for hours and a timer would
529
+ * kill a healthy one. So nothing was left that could tell that shell from a
530
+ * host that vanished without a FIN or an RST — a lost node, a partition, a
531
+ * middlebox that drops idle state. TCP keepalive proves only that the peer's
532
+ * KERNEL answers, and a `healthz` proves only that a FRESH connection is
533
+ * served; neither says anything about the stream in hand.
534
+ *
535
+ * **Negotiated per stream, in both directions.** The open request carries
536
+ * {@link TerminalOpenRequest.heartbeatMs} / {@link TcpConnectRequest.heartbeatMs};
537
+ * a guest that implements this echoes the interval it will use back in its
538
+ * `ready` event and only then starts sending, and the host only starts once
539
+ * that echo arrived. An agent that predates the field ignores it and echoes
540
+ * nothing, so the host behaves exactly as it did; an older HOST — which ends
541
+ * a stream with an error on any frame type it does not know — is never sent
542
+ * one, because it never asked.
543
+ *
544
+ * Anything arriving from the other side counts as proof of life, not just
545
+ * this frame and not even a whole frame: both sides count BYTES, so a single
546
+ * large frame that takes longer than the window to arrive cannot be read as
547
+ * the peer having gone away. {@link STREAM_HEARTBEAT_MISS_LIMIT} consecutive
548
+ * intervals with nothing at all end the stream: the host resolves `exited`
549
+ * with `exitCode: -1` (what a closed socket already produces) or resolves
550
+ * `closed`, and the guest runs the same close cleanup it runs for a socket
551
+ * that went away. Detection lands within those intervals plus at most one
552
+ * watchdog tick, since each side polls at a quarter of the interval rather
553
+ * than at it. Silence while a side has paused reading for backpressure is
554
+ * not silence — that side chose it, and the bytes are waiting in the kernel.
555
+ */
556
+ export type StreamHeartbeat = {
557
+ readonly type: 'heartbeat';
156
558
  };
559
+ /** Missed intervals that end a stream. Three, so one lost frame is not fatal. */
560
+ export declare const STREAM_HEARTBEAT_MISS_LIMIT = 3;
561
+ /**
562
+ * The shortest interval either side will run a heartbeat at.
563
+ *
564
+ * The interval arrives from the host, so the guest clamps it to this before
565
+ * using it and echoes the CLAMPED value — otherwise an authenticated host
566
+ * could ask for a fraction of a millisecond and leave the agent doing
567
+ * nothing but writing heartbeats.
568
+ */
569
+ export declare const MIN_STREAM_HEARTBEAT_MS = 100;
570
+ /**
571
+ * How far above what it asked for a host will honour the guest's echo.
572
+ *
573
+ * The echo is a number from the pod, and the host does its own watchdog
574
+ * arithmetic with it: unclamped, a guest echoing a fraction of a millisecond
575
+ * makes the host tear the stream down on its first tick, and one echoing a
576
+ * day disables the host's detection entirely. A guest that clamps the way
577
+ * this one does always echoes a value inside the band, so the honest case is
578
+ * never altered.
579
+ */
580
+ export declare const STREAM_HEARTBEAT_MAX_ECHO_FACTOR = 4;
581
+ /**
582
+ * The `healthz` feature string an agent advertises when it understands
583
+ * {@link StreamHeartbeat}. Informational for the host — the per-stream
584
+ * `ready` echo is what actually arms anything — and the honest answer for an
585
+ * operator reading a `healthz` reply to find out what an image can do.
586
+ */
587
+ export declare const STREAM_HEARTBEAT_FEATURE = "stream-heartbeat";
157
588
  /** `/read-file` response. `content` is base64 on success. */
158
589
  export interface ReadFileResponse {
159
590
  readonly ok: boolean;
160
591
  readonly content?: string;
592
+ /** The WHOLE file's size, in both the whole-file and the ranged shape. */
161
593
  readonly sizeBytes?: number;
162
594
  readonly encoding?: string;
163
595
  readonly error?: string;
596
+ /** Present only on a ranged reply: the first byte `content` starts at. */
597
+ readonly offset?: number;
598
+ /**
599
+ * Present only on a ranged reply: how many bytes `content` decodes to.
600
+ * Below the requested `length` when the range ran past EOF, which is an
601
+ * answer rather than an error.
602
+ */
603
+ readonly bytesRead?: number;
164
604
  }
165
605
  /**
166
606
  * Accumulates the streamed `/execute` NDJSON into a single
@@ -201,4 +641,15 @@ export declare class ExecResultAccumulator {
201
641
  * ignored; malformed JSON and unknown/partial event shapes are refused.
202
642
  */
203
643
  export declare function parseExecLine(line: string): ExecEvent | undefined;
644
+ /**
645
+ * The same structural validation over an event that has ALREADY been
646
+ * parsed out of its frame.
647
+ *
648
+ * Split out of {@link parseExecLine} for the caller that reads the exec
649
+ * stream frame by frame rather than as NDJSON text — the Kubernetes
650
+ * detached execution, which needs the raw object to read the retained-log
651
+ * offsets off it. One validation, two entry points: an ordinary exec and a
652
+ * detached one must never disagree about what a valid frame is.
653
+ */
654
+ export declare function parseExecEvent(parsed: unknown): ExecEvent;
204
655
  //# sourceMappingURL=protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/backends/firecracker/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/backends/firecracker/protocol.ts"],"names":[],"mappings":"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"}