@cortexkit/subc-client 0.4.1 → 0.8.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.
@@ -1 +1 @@
1
- {"version":3,"file":"socket.js","sourceRoot":"","sources":["../src/socket.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"socket.js","sourceRoot":"","sources":["../src/socket.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/subc-client",
3
- "version": "0.4.1",
3
+ "version": "0.8.0",
4
4
  "description": "TypeScript client for the subc daemon. Wire-compatible (byte-for-byte) with the Rust subc-transport handshake and subc-protocol envelope.",
5
5
  "type": "module",
6
6
  "exports": {
package/src/auth.ts CHANGED
@@ -16,7 +16,7 @@
16
16
  import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
17
17
 
18
18
  import type { ConnectionInfo } from "./connection-file.js";
19
- import { SubcSocket } from "./socket.js";
19
+ import { SubcSocket, writeBorrowed } from "./socket.js";
20
20
 
21
21
  export const NONCE_LEN = 32;
22
22
  export const PROOF_LEN = 32;
@@ -59,8 +59,8 @@ async function writeMessage(
59
59
  }
60
60
  const lenPrefix = new Uint8Array(4);
61
61
  new DataView(lenPrefix.buffer).setUint32(0, json.length, true);
62
- await sock.write(lenPrefix, deadlineMs);
63
- await sock.write(json, deadlineMs);
62
+ await writeBorrowed(sock, lenPrefix, deadlineMs);
63
+ await writeBorrowed(sock, json, deadlineMs);
64
64
  }
65
65
 
66
66
  async function readMessage<T>(sock: SubcSocket, deadlineMs: number): Promise<T> {
@@ -78,10 +78,22 @@ async function readMessage<T>(sock: SubcSocket, deadlineMs: number): Promise<T>
78
78
  }
79
79
 
80
80
  interface ServerProofMessage {
81
- daemon_id: number[];
82
- server_nonce: number[];
81
+ daemon_id: unknown;
82
+ server_nonce: unknown;
83
83
  daemon_ver: string;
84
- server_proof: number[];
84
+ server_proof: unknown;
85
+ }
86
+
87
+ function authBytes(value: unknown, field: string): Uint8Array {
88
+ if (!Array.isArray(value)) {
89
+ throw new AuthError(`auth field '${field}' must be a byte array`);
90
+ }
91
+ for (const byte of value) {
92
+ if (typeof byte !== "number" || !Number.isInteger(byte) || byte < 0 || byte > 255) {
93
+ throw new AuthError(`auth field '${field}' has invalid byte ${String(byte)}`);
94
+ }
95
+ }
96
+ return Uint8Array.from(value as number[]);
85
97
  }
86
98
 
87
99
  /**
@@ -103,9 +115,9 @@ export async function authenticateClient(
103
115
  );
104
116
 
105
117
  const proof = await readMessage<ServerProofMessage>(sock, deadlineMs);
106
- const serverNonce = Uint8Array.from(proof.server_nonce);
107
- const daemonId = Uint8Array.from(proof.daemon_id);
108
- const serverProof = Uint8Array.from(proof.server_proof);
118
+ const serverNonce = authBytes(proof.server_nonce, "server_nonce");
119
+ const daemonId = authBytes(proof.daemon_id, "daemon_id");
120
+ const serverProof = authBytes(proof.server_proof, "server_proof");
109
121
 
110
122
  const expected = computeProof(conn.key, SERVER_PROOF_DOMAIN, clientNonce, serverNonce, daemonId);
111
123
  if (!constantTimeEq(expected, serverProof)) {
package/src/client.ts CHANGED
@@ -37,6 +37,8 @@ import {
37
37
  SocketWriteNotQueuedError,
38
38
  SocketWriteQueuedError,
39
39
  SubcSocket,
40
+ writeBorrowed,
41
+ writeTrackedBorrowed,
40
42
  } from "./socket.js";
41
43
 
42
44
  const debug = debuglog("subc-client");
@@ -54,6 +56,7 @@ const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
54
56
  // NOT a deadline extension: an absent reply still settles right after the check
55
57
  // phase. Capped so it can never approach BODY_READ_TIMEOUT_MS.
56
58
  const TIMEOUT_ARBITRATION_GRACE_MS = 50;
59
+ const LIVENESS_PROBE_WINDOW_MS = 2000;
57
60
  // Internal marker set as the `code` on the SubcError a request-deadline timeout
58
61
  // rejects with, so the managed classifier can tell a deadline (reply may simply
59
62
  // not have been read in time) from an actual connection drop. Never surfaced to
@@ -210,13 +213,14 @@ export class SubcCallError extends Error {
210
213
  /**
211
214
  * A live subscription to a provider's event stream, riding a single held-open
212
215
  * request. `onEvent` fires for each StreamData frame; `closed` resolves when the
213
- * provider ends the stream (StreamEnd) and rejects on an Error terminal or a route
214
- * GOODBYE. `unsubscribe` cancels the held-open request so the provider unwinds.
216
+ * provider ends the stream (StreamEnd) or the consumer unsubscribes, and rejects on
217
+ * an Error terminal or a route GOODBYE. `unsubscribe` cancels the held-open request
218
+ * so the provider unwinds.
215
219
  */
216
220
  export interface Subscription {
217
221
  /** Cancel the subscription: sends Cancel on the held-open request; idempotent. */
218
222
  unsubscribe(): void;
219
- /** Resolves on StreamEnd; rejects on an Error terminal or route close. */
223
+ /** Resolves on StreamEnd or local unsubscribe; rejects on an Error terminal or route close. */
220
224
  readonly closed: Promise<void>;
221
225
  }
222
226
 
@@ -257,6 +261,15 @@ export interface ConnectOptions {
257
261
  reconnectBackoff?: ReconnectBackoff;
258
262
  /** Injectable sleep for timer-free reconnect tests. */
259
263
  sleep?: (ms: number) => Promise<void>;
264
+ /**
265
+ * Window the post-deadline liveness probe waits for ANY inbound frame after
266
+ * sending its channel-0 Ping before convicting the socket as half-open.
267
+ * Genuine event-loop starvation self-protects at any setting: a loop starved
268
+ * enough to delay the probe's check also delays the read loop, and when it
269
+ * wakes the buffered Pong dispatches first. Exposed for deterministic tests.
270
+ */
271
+ livenessProbeWindowMs?: number;
272
+
260
273
  /**
261
274
  * Hard cap on the timeout-arbitration grace window (see
262
275
  * TIMEOUT_ARBITRATION_GRACE_MS). A reply whose bytes are actively arriving when
@@ -265,6 +278,26 @@ export interface ConnectOptions {
265
278
  * exposed mainly so tests can prove the arbitration deterministically.
266
279
  */
267
280
  timeoutArbitrationGraceMs?: number;
281
+ /**
282
+ * Observer for daemon-originated channel-0 control pushes (`route.closing`,
283
+ * `route.closed`, and any op added later). Purely advisory: the daemon's
284
+ * load-bearing route-death signal remains the GOODBYE frame, and nothing in
285
+ * the client's own route lifecycle consumes these. The contract is the wire
286
+ * contract verbatim -- unrecognized ops still arrive here (callers ignore
287
+ * what they don't know, per the MUST-ignore clause), a push that fails to
288
+ * parse as JSON is dropped without surfacing, and an observer throw is
289
+ * swallowed like every other caller callback so it cannot fail the read loop
290
+ * or unrelated requests.
291
+ */
292
+ onControlPush?: (push: ControlPush) => void;
293
+ }
294
+
295
+ /** A parsed daemon-originated channel-0 control push. */
296
+ export interface ControlPush {
297
+ /** The push discriminator, e.g. "route.closing" | "route.closed". */
298
+ op: string;
299
+ /** The full parsed body, `op` included, for op-specific fields. */
300
+ body: Record<string, unknown>;
268
301
  }
269
302
 
270
303
  interface NormalizedConnectOptions {
@@ -275,6 +308,8 @@ interface NormalizedConnectOptions {
275
308
  reconnectBackoff: ReconnectBackoff;
276
309
  sleep: (ms: number) => Promise<void>;
277
310
  timeoutArbitrationGraceMs: number;
311
+ livenessProbeWindowMs: number;
312
+ onControlPush?: (push: ControlPush) => void;
278
313
  }
279
314
 
280
315
  interface OpenedConnection {
@@ -423,11 +458,20 @@ export class SubcClient {
423
458
  // double-execute anything. The cached bind is dead (module restarted and
424
459
  // its route-gone GOODBYE raced or was missed); evict it so the retry
425
460
  // re-opens the route instead of resending into the same dead channel.
426
- if (err.code === "unknown_channel" && !retriedUnknownChannel && !this.closeStarted) {
461
+ // stale_route_epoch is the same class with a sharper cause (subconscious
462
+ // issue #39): the channel is known but its epoch was released while this
463
+ // request was in flight. The daemon's contract for the code is
464
+ // NOT-FORWARDED — dropped before delivery — so the retry is safe by
465
+ // construction, and the remedy is identical: evict, re-open, resend once.
466
+ const deadBindCode = err.code === "unknown_channel" || err.code === "stale_route_epoch";
467
+ if (deadBindCode && !retriedUnknownChannel && !this.closeStarted) {
427
468
  retriedUnknownChannel = true;
428
469
  this.evictRouteHandle(routeHandle);
429
470
  continue;
430
471
  }
472
+ if (deadBindCode && retriedUnknownChannel) {
473
+ this.evictRouteHandle(routeHandle);
474
+ }
431
475
  if (err.kind === "not_sent") {
432
476
  try {
433
477
  await this.reconnectAfterDrop(err);
@@ -442,6 +486,14 @@ export class SubcClient {
442
486
  // late under load), so tearing it down would abandon a healthy connection
443
487
  // and its other in-flight routes for nothing.
444
488
  this.scheduleReconnectAfterDrop(err);
489
+ } else if (err.kind === "outcome_unknown" && err.code === DEADLINE_NO_DROP_CODE) {
490
+ // Keeping the socket is only correct when the socket is actually
491
+ // alive. A HALF-OPEN socket (peer gone with no FIN/RST — the
492
+ // post-sleep/wake shape) produces the identical observable, and
493
+ // keeping it pins every future call to a corpse: this exact keep
494
+ // turned one host sleep into a whole session's tool outage. The
495
+ // probe supplies the discriminator neither timer can.
496
+ this.probeLivenessAfterDeadline();
445
497
  }
446
498
  throw err;
447
499
  }
@@ -462,19 +514,23 @@ export class SubcClient {
462
514
  const corr = this.allocateCorr();
463
515
  const key = pendingKey(handle, corr);
464
516
 
517
+ let subscriptionPending: Pending | null = null;
518
+ let resolveClosed: (() => void) | null = null;
465
519
  const closed = new Promise<void>((resolve, reject) => {
466
520
  if (this.closedErr) {
467
521
  reject(this.closedErr);
468
522
  return;
469
523
  }
470
- this.pending.set(key, {
524
+ resolveClosed = resolve;
525
+ subscriptionPending = {
471
526
  handle,
472
527
  resolve: () => resolve(),
473
528
  reject,
474
529
  onProgress: onEvent,
475
530
  timer: null,
476
531
  subscription: true,
477
- });
532
+ };
533
+ this.pending.set(key, subscriptionPending);
478
534
  const frame = buildFrame(
479
535
  FrameType.Request,
480
536
  buildFlags(false, priority, false, admission),
@@ -483,7 +539,7 @@ export class SubcClient {
483
539
  corr,
484
540
  bytes,
485
541
  );
486
- this.sock.write(encodeFrame(frame), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch((err) => {
542
+ writeBorrowed(this.sock, encodeFrame(frame), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch((err) => {
487
543
  const pending = this.pending.get(key);
488
544
  if (pending) this.rejectPending(key, pending, err instanceof Error ? err : new SubcError(String(err)));
489
545
  });
@@ -493,7 +549,8 @@ export class SubcClient {
493
549
  const unsubscribe = (): void => {
494
550
  if (cancelled) return;
495
551
  cancelled = true;
496
- this.cancel(handle, corr, priority);
552
+ if (subscriptionPending && resolveClosed) this.settle(key, subscriptionPending, resolveClosed);
553
+ if (this.isLiveHandle(handle)) this.cancel(handle, corr, priority);
497
554
  };
498
555
  return { unsubscribe, closed };
499
556
  }
@@ -509,7 +566,7 @@ export class SubcClient {
509
566
  corr,
510
567
  EMPTY_BODY,
511
568
  );
512
- this.sock.write(encodeFrame(cancel), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch(() => undefined);
569
+ writeBorrowed(this.sock, encodeFrame(cancel), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch(() => undefined);
513
570
  }
514
571
 
515
572
  /** Poll status or liveness for exactly the supplied route generation. */
@@ -604,7 +661,7 @@ export class SubcClient {
604
661
  0n,
605
662
  EMPTY_BODY,
606
663
  );
607
- const write = this.sock.writeTracked(encodeFrame(goodbye), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS);
664
+ const write = writeTrackedBorrowed(this.sock, encodeFrame(goodbye), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS);
608
665
  if (!write.queued && closeOnQueueFailure) this.closeConnectionAfterCleanupFailure();
609
666
  write.completed.catch(() => {
610
667
  if (closeOnQueueFailure && !write.queued) this.closeConnectionAfterCleanupFailure();
@@ -676,7 +733,7 @@ export class SubcClient {
676
733
  };
677
734
  pending.timer = setTimeout(() => this.arbitrateTimeout(key, pending, channel, corr, ms), ms);
678
735
  this.pending.set(key, pending);
679
- this.sock.write(encodeFrame(frame), Date.now() + ms).catch((error) => {
736
+ writeBorrowed(this.sock, encodeFrame(frame), Date.now() + ms).catch((error) => {
680
737
  const current = this.pending.get(key);
681
738
  if (current) this.rejectPending(key, current, error instanceof Error ? error : new SubcError(String(error)));
682
739
  });
@@ -794,7 +851,7 @@ export class SubcClient {
794
851
  };
795
852
  pending.timer = setTimeout(() => this.arbitrateTimeout(key, pending, handle.channel, corr, ms), ms);
796
853
  this.pending.set(key, pending);
797
- const write = this.sock.writeTracked(encodeFrame(frame), Date.now() + ms);
854
+ const write = writeTrackedBorrowed(this.sock, encodeFrame(frame), Date.now() + ms);
798
855
  handedToSocket = write.queued;
799
856
  write.completed.catch((error) => {
800
857
  const current = this.pending.get(key);
@@ -891,6 +948,73 @@ export class SubcClient {
891
948
  }
892
949
  }
893
950
 
951
+ // Stamped by dispatch() on every inbound frame; read by the liveness probe.
952
+ private lastInboundAtMs = 0;
953
+ // Single-flight guard: overlapping deadline-no-drop settles share one probe.
954
+ private livenessProbe: Promise<void> | null = null;
955
+
956
+ /**
957
+ * Discriminate event-loop starvation from a half-open socket after a
958
+ * deadline-no-drop settle. The arbitration deliberately keeps the socket on
959
+ * that verdict (a late-read reply under load must not cost a healthy
960
+ * connection), but a half-open socket — peer vanished with no FIN/RST, as
961
+ * after host sleep/wake — yields the SAME verdict forever, so the keep
962
+ * becomes a permanent pin to a dead transport. The discriminator is
963
+ * socket-level liveness evidence: send a channel-0 Ping (the daemon always
964
+ * answers — subc-core control.rs) and require ANY inbound frame within the
965
+ * window; the Pong suffices, and a busy socket's other traffic proves the
966
+ * link just as well. Silence convicts: the socket is failed with a named
967
+ * cause and closed, so the ordinary drop path (pending rejection now,
968
+ * reconnect on the next call) takes over.
969
+ *
970
+ * Starvation cannot be falsely convicted by a short window: a loop starved
971
+ * enough to delay the read loop delays this probe's own timer identically,
972
+ * and when both wake the buffered Pong dispatches before the check runs.
973
+ *
974
+ * Scope: hooked from the managed-call path only. Control-plane requests
975
+ * (route.open, catalog.list) are short-lived and their failures already
976
+ * escalate through reconnect classification; the managed path is where a
977
+ * plugin lives for hours and where the pin was observed in production.
978
+ */
979
+ private probeLivenessAfterDeadline(): void {
980
+ if (this.livenessProbe || this.closeStarted || this.closedErr) return;
981
+ const sock = this.sock;
982
+ const generation = this.generation;
983
+ let corr: bigint;
984
+ try {
985
+ corr = this.allocateCorr();
986
+ } catch {
987
+ return; // allocator exhausted: the next reconnect resets it
988
+ }
989
+ const t0 = Date.now();
990
+ const ping = buildFrame(
991
+ FrameType.Ping,
992
+ buildFlags(false, Priority.Interactive, false, AdmissionClass.Normal),
993
+ 0,
994
+ 0,
995
+ corr,
996
+ new Uint8Array(),
997
+ );
998
+ const probe = (async (): Promise<void> => {
999
+ // A failed WRITE is not exonerating: swallow it and let the window
1000
+ // check run — a socket that cannot carry a Ping will not produce an
1001
+ // inbound frame either, and conviction is the right verdict.
1002
+ await writeBorrowed(sock, encodeFrame(ping), t0 + this.opts.livenessProbeWindowMs).catch(() => {});
1003
+ await this.opts.sleep(this.opts.livenessProbeWindowMs);
1004
+ if (this.sock !== sock || this.generation !== generation || this.closeStarted) return;
1005
+ if (this.lastInboundAtMs >= t0) return; // link proven — keep the socket
1006
+ this.fail(
1007
+ new SocketClosedError(
1008
+ `liveness probe convicted a half-open socket: no inbound frame for ${this.opts.livenessProbeWindowMs}ms after a channel-0 Ping (deadline-no-drop settles preceded this); closing so the next call reconnects`,
1009
+ ),
1010
+ );
1011
+ sock.close();
1012
+ })().finally(() => {
1013
+ this.livenessProbe = null;
1014
+ });
1015
+ this.livenessProbe = probe;
1016
+ }
1017
+
894
1018
  private async ensureConnectedForManaged(): Promise<void> {
895
1019
  if (this.closeStarted) throw new SubcError("client closed");
896
1020
  if (this.reconnecting) await this.reconnecting;
@@ -1023,6 +1147,37 @@ export class SubcClient {
1023
1147
  }
1024
1148
 
1025
1149
  private dispatch(frame: Frame): void {
1150
+ // Every dispatched frame proves the socket delivers inbound bytes; the
1151
+ // post-deadline liveness probe reads this stamp. Stamped after readLoop's
1152
+ // generation gate, so a stale socket's late frames never vouch for the
1153
+ // live one.
1154
+ this.lastInboundAtMs = Date.now();
1155
+ if (frame.header.channel === 0 && frame.header.ty === FrameType.Push) {
1156
+ // Daemon-originated control push (route.closing / route.closed / future
1157
+ // ops). Never matches a pending (corr is daemon-chosen), never an error
1158
+ // path: unparseable bodies and absent observers both drop silently per
1159
+ // the wire contract's MUST-ignore clause, and an observer throw is
1160
+ // swallowed for the same reason as onProgress below -- a caller callback
1161
+ // must not fail the read loop.
1162
+ const observer = this.opts.onControlPush;
1163
+ if (observer) {
1164
+ let parsed: ControlPush | null = null;
1165
+ try {
1166
+ const body = this.parseJson(frame) as Record<string, unknown>;
1167
+ if (body && typeof body.op === "string") parsed = { op: body.op, body };
1168
+ } catch {
1169
+ // Unparseable control push: ignored by contract.
1170
+ }
1171
+ if (parsed) {
1172
+ try {
1173
+ observer(parsed);
1174
+ } catch {
1175
+ // Observer's own throw, on its own stack; the stream must survive.
1176
+ }
1177
+ }
1178
+ }
1179
+ return;
1180
+ }
1026
1181
  let handle: RouteHandle | null = null;
1027
1182
  if (frame.header.channel !== 0) {
1028
1183
  handle = this.liveRoutes.get(frame.header.channel) ?? null;
@@ -1036,11 +1191,32 @@ export class SubcClient {
1036
1191
  const pending = this.pending.get(key);
1037
1192
  if (pending) {
1038
1193
  if (pending.acceptFrame && !pending.acceptFrame(frame)) return;
1039
- switch (frame.header.ty) {
1040
- case FrameType.Push:
1041
- case FrameType.StreamData:
1042
- pending.onProgress?.(frame.body);
1043
- return;
1194
+ switch (frame.header.ty) {
1195
+ case FrameType.Push:
1196
+ case FrameType.StreamData:
1197
+ // A THROW FROM CALLER CODE MUST NOT REACH THE READ LOOP.
1198
+ //
1199
+ // `onProgress` (and `onEvent`, which is the same slot) is supplied by
1200
+ // the caller and runs INSIDE readLoop's frame dispatch. An escaping
1201
+ // throw unwinds into readLoop's catch, which treats it as a socket
1202
+ // failure: it calls fail(), rejecting EVERY in-flight request on this
1203
+ // connection -- other routes included -- with the caller's own error as
1204
+ // the reported cause, and stops reading. One consumer's bad event
1205
+ // handler therefore drops the whole connection, and the surfaced error
1206
+ // names the handler rather than the transport, so the failure reads as
1207
+ // a subc fault.
1208
+ //
1209
+ // Swallowing is deliberate and is NOT hiding a fault from the caller:
1210
+ // the throw happened in their own callback, on their own stack, where
1211
+ // they are the party able to catch it. What the client owes them is
1212
+ // that the stream and every sibling route keep working.
1213
+ try {
1214
+ pending.onProgress?.(frame.body);
1215
+ } catch {
1216
+ // Swallow the caller's own handler error so one bad callback cannot
1217
+ // abort the read loop or fail unrelated requests. See above.
1218
+ }
1219
+ return;
1044
1220
  case FrameType.Response:
1045
1221
  case FrameType.StreamEnd:
1046
1222
  this.settle(key, pending, () => pending.resolve(frame));
@@ -1061,7 +1237,17 @@ export class SubcClient {
1061
1237
  }
1062
1238
 
1063
1239
  if (frame.header.ty === FrameType.Goodbye && handle) {
1064
- this.failHandle(handle, new SubcError("route closed by subc (GOODBYE)"));
1240
+ // Carries `route_closed` like the other two route-close sites (closeRoute,
1241
+ // late route.open). It was the only one without a code, so a consumer
1242
+ // branching on `route_closed` to recognise a gone route saw this one as an
1243
+ // uncoded generic failure and fell through to whatever its default was.
1244
+ //
1245
+ // THE CODE MUST NOT MAKE THIS RETRYABLE. A GOODBYE arriving mid-request
1246
+ // means the request was already forwarded and the module may have run it,
1247
+ // so it stays kind=outcome_unknown -- the same class as a mid-flight socket
1248
+ // drop, and never the not_sent/unknown_channel class that call() retries.
1249
+ // The code says WHICH route ended, not that it is safe to send again.
1250
+ this.failHandle(handle, new SubcError("route closed by subc (GOODBYE)", "route_closed"));
1065
1251
  if (this.liveRoutes.get(handle.channel) === handle) this.liveRoutes.delete(handle.channel);
1066
1252
  this.evictRouteHandle(handle);
1067
1253
  return;
@@ -1199,11 +1385,12 @@ export class SubcClient {
1199
1385
  }
1200
1386
 
1201
1387
  private encode(value: unknown): Uint8Array {
1202
- return new Uint8Array(Buffer.from(JSON.stringify(value), "utf8"));
1388
+ return Buffer.from(JSON.stringify(value), "utf8");
1203
1389
  }
1204
1390
 
1205
1391
  private parseJson(frame: Frame): unknown {
1206
- return JSON.parse(Buffer.from(frame.body).toString("utf8"));
1392
+ const b = frame.body;
1393
+ return JSON.parse(Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString("utf8"));
1207
1394
  }
1208
1395
  }
1209
1396
 
@@ -1243,6 +1430,7 @@ export function isRetryableRouteOpenCode(code: string | undefined): boolean {
1243
1430
  return (
1244
1431
  code === "unknown_module" ||
1245
1432
  code === "module_reloading" ||
1433
+ code === "module_warming" ||
1246
1434
  code === "target_unavailable" ||
1247
1435
  code === "module_timeout"
1248
1436
  );
@@ -1266,6 +1454,8 @@ function normalizeConnectOptions(opts: ConnectOptions): NormalizedConnectOptions
1266
1454
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
1267
1455
  sleep: opts.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms))),
1268
1456
  timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS,
1457
+ livenessProbeWindowMs: opts.livenessProbeWindowMs ?? LIVENESS_PROBE_WINDOW_MS,
1458
+ onControlPush: opts.onControlPush,
1269
1459
  };
1270
1460
  }
1271
1461
 
@@ -6,6 +6,8 @@
6
6
 
7
7
  import { promises as fs } from "node:fs";
8
8
 
9
+ import { PROTOCOL_VERSION } from "./envelope.js";
10
+
9
11
  export const SCHEMA_VERSION = 1;
10
12
  export const MIN_KEY_LEN = 32;
11
13
  export const DAEMON_ID_LEN = 16;
@@ -29,9 +31,14 @@ export interface ConnectionInfo {
29
31
  export class ConnectionFileError extends Error {}
30
32
 
31
33
  function toBytes(value: unknown, field: string): Uint8Array {
32
- if (!Array.isArray(value) || value.some((n) => typeof n !== "number")) {
34
+ if (!Array.isArray(value)) {
33
35
  throw new ConnectionFileError(`connection file field '${field}' must be a JSON array of bytes`);
34
36
  }
37
+ for (const byte of value) {
38
+ if (typeof byte !== "number" || !Number.isInteger(byte) || byte < 0 || byte > 255) {
39
+ throw new ConnectionFileError(`connection file field '${field}' has invalid byte ${String(byte)}`);
40
+ }
41
+ }
35
42
  return Uint8Array.from(value as number[]);
36
43
  }
37
44
 
@@ -84,6 +91,13 @@ export async function readConnectionFile(path: string): Promise<ConnectionInfo>
84
91
  throw new ConnectionFileError(`connection file JSON read failed for ${path}: ${String(err)}`);
85
92
  }
86
93
 
94
+ const wireVersion = parsed.wire_version;
95
+ if (wireVersion !== undefined && wireVersion !== PROTOCOL_VERSION) {
96
+ throw new ConnectionFileError(
97
+ `connection file wire_version ${String(wireVersion)} but this client speaks ${PROTOCOL_VERSION}; the client library must be upgraded`,
98
+ );
99
+ }
100
+
87
101
  const endpointsRaw = parsed.endpoints;
88
102
  if (!Array.isArray(endpointsRaw)) {
89
103
  throw new ConnectionFileError("connection file 'endpoints' must be an array");
package/src/envelope.ts CHANGED
@@ -122,6 +122,59 @@ export class DecodeError extends Error {
122
122
  }
123
123
  }
124
124
 
125
+ function validateHeaderFields(header: EnvelopeHeader): void {
126
+ // Apply wire-width coercions in serialization order before semantic validation.
127
+ // This preserves encodeHeader's modulo behavior and its early conversion errors.
128
+ const len = header.len >>> 0;
129
+ const ver = (header.ver >>> 0) & 0xff;
130
+ const typeByte = (header.ty >>> 0) & 0xff;
131
+ const flags = (header.flags >>> 0) & 0xff;
132
+ const channel = (header.channel >>> 0) & 0xffff;
133
+ const epoch = header.epoch >>> 0;
134
+ void BigInt.asUintN(64, header.corr);
135
+
136
+ if (ver !== PROTOCOL_VERSION) throw new DecodeError(`unsupported envelope version ${ver}`, "unsupported_version");
137
+ if (typeByte > FRAME_TYPE_MAX) throw new DecodeError(`unknown frame type byte ${typeByte}`, "unknown_frame_type");
138
+ const ty = typeByte as FrameType;
139
+ if ((flags & FLAG_RESERVED_MASK) !== 0) {
140
+ throw new DecodeError(
141
+ `reserved flag bits set in flags 0b${flags.toString(2).padStart(8, "0")}`,
142
+ "reserved_flag_bits",
143
+ );
144
+ }
145
+ if (((flags & FLAG_PRIORITY_MASK) >> FLAG_PRIORITY_SHIFT) === 0b11) {
146
+ throw new DecodeError(
147
+ `reserved priority bits set in flags 0b${flags.toString(2).padStart(8, "0")}`,
148
+ "reserved_priority_bits",
149
+ );
150
+ }
151
+ const admission = (flags & FLAG_ADMISSION_MASK) >> FLAG_ADMISSION_SHIFT;
152
+ if (admission === 0b11) {
153
+ throw new DecodeError(
154
+ `reserved admission class set in flags 0b${flags.toString(2).padStart(8, "0")}`,
155
+ "reserved_admission_class",
156
+ );
157
+ }
158
+ if (admission === AdmissionClass.Sheddable && ty !== FrameType.Push && ty !== FrameType.StreamData) {
159
+ throw new DecodeError(
160
+ `SHEDDABLE admission class is illegal on ${FrameType[ty]} in flags 0b${flags.toString(2).padStart(8, "0")}`,
161
+ "sheddable_illegal_frame_type",
162
+ );
163
+ }
164
+ if (channel === 0 && epoch !== 0) {
165
+ throw new DecodeError(
166
+ `control channel carried nonzero epoch ${epoch}`,
167
+ "nonzero_epoch_on_control_channel",
168
+ );
169
+ }
170
+ if (isPureHeader(ty) && len !== 0) {
171
+ throw new DecodeError(
172
+ `pure-header frame ${FrameType[ty]} declared non-zero body length ${len}`,
173
+ "pure_header_frame_with_body",
174
+ );
175
+ }
176
+ }
177
+
125
178
  /** Decode and validate a header from the front of `bytes`. */
126
179
  export function decodeHeader(bytes: Uint8Array): EnvelopeHeader {
127
180
  if (bytes.length < FROZEN_PREFIX_LEN) {
@@ -210,7 +263,7 @@ export function buildFrameWithVersion(
210
263
  throw new DecodeError(`frame body ${body.length} exceeds max ${MAX_FRAME_BODY_LEN}`, "frame_body_too_large");
211
264
  }
212
265
  const header = { len: body.length, ver, ty, flags, channel, epoch, corr };
213
- decodeHeader(encodeHeader(header));
266
+ validateHeaderFields(header);
214
267
  return { header, body };
215
268
  }
216
269
 
package/src/index.ts CHANGED
@@ -16,6 +16,7 @@ export {
16
16
  type RequestOptions,
17
17
  type ManagedCallOptions,
18
18
  type ConnectOptions,
19
+ type ControlPush,
19
20
  type ReconnectBackoff,
20
21
  type SubcCallErrorKind,
21
22
  type SubscribeOptions,
@@ -70,19 +71,16 @@ export {
70
71
  type BindDecision,
71
72
  type Principal,
72
73
  type BindingsInput,
73
- type CircuitBreakerInput,
74
74
  type Concurrency,
75
75
  type ConsumerRoleInput,
76
76
  type ExecutionMode,
77
77
  type IdentityBindingInput,
78
78
  type IdentityScope,
79
79
  type InternalTransport,
80
- type LeaseScope,
81
80
  type ManagementOperationInput,
82
81
  type ManagementOperationKind,
83
82
  type ManagementSurfaceManifestOptions,
84
83
  type ManifestInput,
85
- type ModelPolicyInput,
86
84
  type ModuleHelloAckBody,
87
85
  type ObservabilityKind,
88
86
  type ObservabilitySurfaceInput,
@@ -95,12 +93,10 @@ export {
95
93
  type ProviderHealthHandler,
96
94
  type ProviderRoleInput,
97
95
  type RouteBindRequest,
98
- type ScheduledTaskInput,
99
96
  type StorageBindingInput,
100
97
  type StorageKind,
101
98
  type StorageScope,
102
99
  type SubcProviderConnectOptions,
103
- type TaskEligibilityInput,
104
100
  type ToolInput,
105
101
  type TrustTier,
106
102
  type VaultGrantInput,