@volter/world-core 3.0.37 → 3.0.39

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 (179) hide show
  1. package/app-route.cjs +26 -25
  2. package/app-route.d.cts +1 -0
  3. package/dist/app-route.cjs +26 -25
  4. package/dist/app-route.d.cts +1 -0
  5. package/dist/generated/pack-facts.json +409 -352
  6. package/dist/inject.cjs +474 -95
  7. package/dist/network-policy.cjs +108 -13
  8. package/dist/network-policy.d.cts +8 -3
  9. package/dist/src/actions.js +2 -1
  10. package/dist/src/anthropic-wire.d.ts +2 -0
  11. package/dist/src/anthropic-wire.js +5 -0
  12. package/dist/src/attestation.d.ts +6 -0
  13. package/dist/src/attestation.js +27 -0
  14. package/dist/src/bytes.d.ts +3 -0
  15. package/dist/src/bytes.js +17 -0
  16. package/dist/src/changeset.js +2 -1
  17. package/dist/src/clickhouse/sql.js +73 -14
  18. package/dist/src/derived-core.d.ts +210 -32
  19. package/dist/src/derived-core.js +510 -244
  20. package/dist/src/derived-real.d.ts +1 -1
  21. package/dist/src/derived-real.js +704 -93
  22. package/dist/src/derived.d.ts +18 -2
  23. package/dist/src/derived.js +21 -2
  24. package/dist/src/events.d.ts +28 -45
  25. package/dist/src/events.js +40 -58
  26. package/dist/src/exact-json.d.ts +10 -0
  27. package/dist/src/exact-json.js +98 -0
  28. package/dist/src/executor.d.ts +17 -0
  29. package/dist/src/executor.js +91 -30
  30. package/dist/src/file-response.js +1 -1
  31. package/dist/src/form.d.ts +8 -0
  32. package/dist/src/form.js +76 -0
  33. package/dist/src/git/format.d.ts +16 -0
  34. package/dist/src/git/format.js +110 -0
  35. package/dist/src/git/index.d.ts +1 -0
  36. package/dist/src/git/index.js +1 -0
  37. package/dist/src/git/lfs.d.ts +1 -1
  38. package/dist/src/git/lfs.js +4 -3
  39. package/dist/src/graphql-wire.d.ts +6 -0
  40. package/dist/src/graphql-wire.js +6 -3
  41. package/dist/src/grpc-wire.js +2 -1
  42. package/dist/src/head.d.ts +1 -0
  43. package/dist/src/head.js +15 -4
  44. package/dist/src/held-reads.d.ts +6 -0
  45. package/dist/src/held-reads.js +60 -0
  46. package/dist/src/history.js +5 -4
  47. package/dist/src/host-port.d.ts +5 -0
  48. package/dist/src/host-port.js +14 -0
  49. package/dist/src/index.d.ts +11 -3
  50. package/dist/src/index.js +9 -4
  51. package/dist/src/log.js +12 -7
  52. package/dist/src/machines.d.ts +81 -5
  53. package/dist/src/machines.js +125 -9
  54. package/dist/src/managed-database.d.ts +15 -11
  55. package/dist/src/managed-database.js +38 -37
  56. package/dist/src/multipart.d.ts +21 -3
  57. package/dist/src/multipart.js +112 -38
  58. package/dist/src/observe.d.ts +3 -0
  59. package/dist/src/observe.js +6 -2
  60. package/dist/src/openai-wire.d.ts +16 -0
  61. package/dist/src/openai-wire.js +43 -12
  62. package/dist/src/pack-fetch.d.ts +4 -6
  63. package/dist/src/pack-fetch.js +189 -57
  64. package/dist/src/packRegistry.d.ts +7 -1
  65. package/dist/src/packRegistry.js +20 -3
  66. package/dist/src/private-transport.d.ts +1 -0
  67. package/dist/src/private-transport.js +11 -0
  68. package/dist/src/protobuf.js +10 -4
  69. package/dist/src/rateBudget.d.ts +8 -1
  70. package/dist/src/rateBudget.js +1 -0
  71. package/dist/src/redis/engine.d.ts +14 -5
  72. package/dist/src/redis/engine.js +271 -72
  73. package/dist/src/redis/frames.d.ts +17 -0
  74. package/dist/src/redis/frames.js +123 -0
  75. package/dist/src/redis/index.d.ts +6 -0
  76. package/dist/src/redis/index.js +6 -0
  77. package/dist/src/redis/json.d.ts +2 -0
  78. package/dist/src/redis/json.js +14 -0
  79. package/dist/src/redis/lua-libs.d.ts +4 -0
  80. package/dist/src/redis/lua-libs.js +173 -0
  81. package/dist/src/redis/lua.d.ts +1 -0
  82. package/dist/src/redis/lua.js +36 -0
  83. package/dist/src/redis/member-storage.d.ts +5 -0
  84. package/dist/src/redis/member-storage.js +75 -0
  85. package/dist/src/redis/resp2.d.ts +4 -0
  86. package/dist/src/redis/resp2.js +29 -0
  87. package/dist/src/redis/stream.d.ts +14 -0
  88. package/dist/src/redis/stream.js +335 -0
  89. package/dist/src/remote-execute.d.ts +2 -2
  90. package/dist/src/request-body.d.ts +11 -0
  91. package/dist/src/request-body.js +11 -0
  92. package/dist/src/runtime.d.ts +6 -5
  93. package/dist/src/runtime.js +5 -5
  94. package/dist/src/s3/wire.d.ts +4 -4
  95. package/dist/src/s3/wire.js +5 -3
  96. package/dist/src/scenario.d.ts +22 -0
  97. package/dist/src/scenario.js +35 -31
  98. package/dist/src/serve-http.d.ts +2 -1
  99. package/dist/src/serve-http.js +10 -1
  100. package/dist/src/serve.js +7 -4
  101. package/dist/src/signing.d.ts +23 -5
  102. package/dist/src/signing.js +74 -11
  103. package/dist/src/sigv4.d.ts +3 -1
  104. package/dist/src/sigv4.js +4 -2
  105. package/dist/src/smtp.js +2 -1
  106. package/dist/src/sockets.js +8 -3
  107. package/dist/src/state-system.d.ts +3 -0
  108. package/dist/src/storage.js +5 -2
  109. package/dist/src/twin-fetch.d.ts +3 -1
  110. package/dist/src/twin-fetch.js +3 -2
  111. package/dist/src/vendor-call.d.ts +10 -3
  112. package/dist/src/vendor-call.js +58 -14
  113. package/dist/test-fixtures/attestation.SOURCE.md +1 -0
  114. package/dist/test-fixtures/attestation.json +50 -0
  115. package/generated/pack-facts.json +409 -352
  116. package/inject.cjs +474 -95
  117. package/network-policy.cjs +108 -13
  118. package/network-policy.d.cts +8 -3
  119. package/package.json +11 -4
  120. package/src/actions.ts +2 -1
  121. package/src/anthropic-wire.ts +6 -0
  122. package/src/attestation.ts +23 -0
  123. package/src/bytes.ts +21 -0
  124. package/src/changeset.ts +2 -1
  125. package/src/clickhouse/sql.ts +50 -16
  126. package/src/derived-core.ts +573 -249
  127. package/src/derived-real.ts +552 -42
  128. package/src/derived.ts +23 -4
  129. package/src/events.ts +54 -85
  130. package/src/exact-json.ts +71 -0
  131. package/src/executor.ts +86 -27
  132. package/src/file-response.ts +1 -1
  133. package/src/form.ts +66 -0
  134. package/src/git/format.ts +89 -0
  135. package/src/git/index.ts +1 -0
  136. package/src/git/lfs.ts +5 -4
  137. package/src/graphql-wire.ts +8 -3
  138. package/src/grpc-wire.ts +2 -1
  139. package/src/head.ts +15 -5
  140. package/src/held-reads.ts +54 -0
  141. package/src/history.ts +5 -4
  142. package/src/host-port.ts +9 -0
  143. package/src/index.ts +10 -4
  144. package/src/log.ts +11 -7
  145. package/src/machines.ts +135 -13
  146. package/src/managed-database.ts +48 -40
  147. package/src/multipart.ts +110 -35
  148. package/src/observe.ts +6 -3
  149. package/src/openai-wire.ts +45 -14
  150. package/src/pack-fetch.ts +173 -50
  151. package/src/packRegistry.ts +27 -4
  152. package/src/private-transport.ts +8 -0
  153. package/src/protobuf.ts +8 -4
  154. package/src/rateBudget.ts +6 -1
  155. package/src/redis/engine.ts +168 -63
  156. package/src/redis/frames.ts +53 -0
  157. package/src/redis/index.ts +6 -0
  158. package/src/redis/json.ts +13 -0
  159. package/src/redis/lua-libs.ts +62 -0
  160. package/src/redis/lua.ts +20 -0
  161. package/src/redis/member-storage.ts +58 -0
  162. package/src/redis/resp2.ts +25 -0
  163. package/src/redis/stream.ts +102 -0
  164. package/src/remote-execute.ts +2 -2
  165. package/src/request-body.ts +12 -0
  166. package/src/runtime.ts +6 -5
  167. package/src/s3/wire.ts +8 -5
  168. package/src/scenario.ts +34 -13
  169. package/src/serve-http.ts +11 -2
  170. package/src/serve.ts +4 -3
  171. package/src/signing.ts +71 -17
  172. package/src/sigv4.ts +5 -3
  173. package/src/smtp.ts +3 -2
  174. package/src/sockets.ts +8 -3
  175. package/src/state-system.ts +3 -0
  176. package/src/storage.ts +5 -2
  177. package/src/twin-fetch.ts +4 -3
  178. package/src/vendor-call.ts +59 -12
  179. package/test-fixtures/attestation.json +50 -0
@@ -1,3 +1,5 @@
1
+ import { parseExactJson } from "./exact-json.js";
2
+ import { readHostPort } from "./host-port.js";
1
3
  // A Protocol 3 pack's whole HTTP surface, served by the kernel from the pack's declarations (docs/contributing/
2
4
  // architecture.md, "The pack contract: the kernel's root"): the discovery door (`GET /twin`, the manifest's
3
5
  // `discovery`), the vendor's own moves as time passes (`semantics/clock.ts`), the World's doors (the manifest's `doors`,
@@ -10,7 +12,7 @@ import { placedCookies, TWIN_PREFIX_HEADER } from "./twin-fetch.js";
10
12
  import { PREFIX_PARAMS_HEADER } from "./derived.js";
11
13
  import { withHeaders } from "./with-headers.js";
12
14
  import { authRefusal, bindSemantics, contextFor, LANE_HEADER, SCENARIO_DECISION_HEADER, coreFor, crossCutting, derivedRequestScopes, vendorError } from "./derived-core.js";
13
- import { compileSurface, createDerivedFetch, matchOperation } from "./derived.js";
15
+ import { compileSurface, createDerivedFetch, matchOperation, pathParams } from "./derived.js";
14
16
  import { isReadOnlyRequest, READ_ONLY_REQUEST_HEADER, runAsVendorMove } from "./request-scope.js";
15
17
  import { parseScenarioDocument, ScenarioEngine, ScenarioError, statefulTwinManifest, twinManifest } from "./scenario.js";
16
18
  import { getActiveWorldStore } from "./world-store.js";
@@ -21,10 +23,12 @@ import { contentAddressOf } from "./content-route.js";
21
23
  import { getPack } from "./packRegistry.js";
22
24
  import { hostRules } from '../host-routing.cjs';
23
25
  import { socketUpgrade } from "./sockets.js";
24
- import { MACHINE_POOL, POOL_KINDS } from "./machines.js";
26
+ import { MACHINE_POOL, POOL_KINDS, resetFakePool } from "./machines.js";
25
27
  import { applyTwinWrite } from "./serve.js";
26
28
  import { graphqlEndpoint } from "./graphql-wire.js";
27
- import { brotliDecompressSync, gunzipSync, gzipSync, inflateSync, zstdDecompressSync } from 'node:zlib';
29
+ import { gzipSync } from 'node:zlib';
30
+ import { decompress } from "./bytes.js";
31
+ import { decodedBodyLimit, oversizedBody, RequestBodyTooLargeError } from "./request-body.js";
28
32
  /** A declared path (`/{account}/r2/api-tokens`, `/<room>`, a door's `/_twin/users/{email}`) as a matcher of a request's
29
33
  * path: the path itself, or `prefix` a path under it too (a screen answers its page and the forms it posts). */
30
34
  function pathMatcher(pattern, prefix) {
@@ -44,6 +48,9 @@ function pathMatcher(pattern, prefix) {
44
48
  }
45
49
  /** A declared host (`dash.cloudflare.com`, `<domain>.daily.co`) as a matcher of a request's host. */
46
50
  function hostMatcher(pattern) {
51
+ const whole = /^(?:\{([^}]+)\}|<([^>]+)>)$/.exec(pattern);
52
+ if (whole)
53
+ return (host) => host ? { params: { [whole[1] ?? whole[2]]: host } } : undefined;
47
54
  const names = [];
48
55
  const re = new RegExp(`^${pattern.split('.').map((label) => {
49
56
  const m = /^(?:\{([^}]+)\}|<([^>]+)>)$/.exec(label);
@@ -58,7 +65,7 @@ function hostMatcher(pattern) {
58
65
  };
59
66
  }
60
67
  /** The host a request is for: the vendor host the World's injector names, else its own. */
61
- const hostOf = (request) => (request.headers.get('x-volter-twin-original-host') ?? request.headers.get('host') ?? new URL(request.url).host).split(':')[0].toLowerCase();
68
+ const hostOf = (request) => readHostPort(request.headers.get('x-volter-twin-original-host') ?? request.headers.get('host') ?? new URL(request.url).host)?.host ?? '';
62
69
  /** The answer for a path no operation, door or screen serves, and for an operation nothing models: the manifest's
63
70
  * `gap`, its `{method}` and `{path}` filled, else the manifest's not-found refusal. */
64
71
  function gapAnswer(m, request, otherMethod = false) {
@@ -68,31 +75,34 @@ function gapAnswer(m, request, otherMethod = false) {
68
75
  return vendorError(m, { ...gap, message: gap.message.replace(/\{method\}/g, request.method).replace(/\{path\}/g, path) });
69
76
  }
70
77
  const METHODS = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'];
71
- const DECODE = { gzip: gunzipSync, zstd: zstdDecompressSync, deflate: inflateSync, br: brotliDecompressSync };
72
78
  /** A request with its body decoded as its Content-Encoding says, when the manifest's `encodings` reads that coding;
73
79
  * undefined when the bytes are not what the header names. */
74
80
  async function decoded(m, request) {
81
+ const codings = (request.headers.get('content-encoding') ?? '').split(',').map(c => c.trim().toLowerCase()).filter(Boolean);
82
+ if (codings.length > 1)
83
+ return new Response('Unsupported Content-Encoding', { status: 415 });
75
84
  if (request.method === 'GET' || request.method === 'HEAD' || request.body === null)
76
85
  return request;
77
86
  // the body read once, here, and every part of the pack given a request made again from its bytes: a served request's
78
87
  // body read through a clone and then read again (an `around` that checks a body before its handler does) tees a stream
79
88
  // whose second branch a Bun server never finishes, and the request hung
80
89
  const raw = new Uint8Array(await request.arrayBuffer());
81
- const coding = (request.headers.get('content-encoding') ?? '').trim().toLowerCase();
90
+ const coding = (codings[0] ?? '');
82
91
  if (!m.encodings?.request?.includes(coding))
83
92
  return new Request(request.url, { method: request.method, headers: request.headers, body: raw });
84
93
  let body;
85
94
  try {
86
- body = DECODE[coding](raw);
95
+ body = await decompress(raw, coding, decodedBodyLimit(m.descriptor?.maxRequestBodySize));
87
96
  }
88
- catch {
89
- return undefined;
97
+ catch (error) {
98
+ return error instanceof RequestBodyTooLargeError ? oversizedBody() : undefined;
90
99
  }
91
100
  const headers = new Headers(request.headers);
92
101
  headers.delete('content-encoding');
93
102
  headers.delete('content-length');
94
- // a copy over an ArrayBuffer of its own: zlib's result may view a shared buffer, which a request body does not take
95
- return new Request(request.url, { method: request.method, headers, body: new Uint8Array(body) });
103
+ // A finite single-chunk stream holds the decoder's buffer; BufferSource extraction would copy the entire body.
104
+ const buffered = new ReadableStream({ start(controller) { controller.enqueue(body); controller.close(); } });
105
+ return new Request(request.url, { method: request.method, headers, body: buffered, duplex: 'half' });
96
106
  }
97
107
  /** An answer in the coding the request accepts, when the manifest's `encodings` answers in it. */
98
108
  async function encoded(m, request, res) {
@@ -108,6 +118,8 @@ async function encoded(m, request, res) {
108
118
  return new Response(gzipSync(new Uint8Array(await res.arrayBuffer())), { status: res.status, statusText: res.statusText, headers });
109
119
  }
110
120
  /** A pack's HTTP surface, as the kernel serves it from the pack's parts. */
121
+ /** A door's path as it is served and listed: under `/_twin/`, whether the manifest writes the prefix or not. */
122
+ const doorPath = (path) => (path.startsWith('/_twin/') ? path : `/_twin${path.startsWith('/') ? '' : '/'}${path}`);
111
123
  export function createPackFetch(parts, options = {}) {
112
124
  const m = parts.manifest;
113
125
  const scope = {
@@ -133,7 +145,7 @@ export function createPackFetch(parts, options = {}) {
133
145
  if (parts.gap) {
134
146
  const url = new URL(request.url);
135
147
  const matched = operation ? matchOperation(routes, request.method, url.pathname, url.searchParams, request.headers) : undefined;
136
- return parts.gap(await contextFor(m, { request, operation: operation ?? { id: 'unmatched', method: request.method, path: url.pathname, class: request.method === 'GET' ? 'retrieve' : 'action' }, params: matched?.params ?? {} }, scope));
148
+ return parts.gap(await contextFor(m, { request, operation: operation ?? { id: 'unmatched', method: request.method, path: url.pathname, class: request.method === 'GET' ? 'retrieve' : 'action' }, params: matched?.params ?? pathParams(routes, url.pathname) }, scope));
137
149
  }
138
150
  const url = new URL(request.url);
139
151
  const other = !matchOperation(routes, request.method, url.pathname, url.searchParams, request.headers)
@@ -165,7 +177,7 @@ export function createPackFetch(parts, options = {}) {
165
177
  if (raw === null)
166
178
  throw new ScenarioError(`${m.vendor} scenario: no file at ${options.scenarioPath}`);
167
179
  if (!engine || raw !== engineRaw) {
168
- engine = new ScenarioEngine(parts.scenario.adapter, parseScenarioDocument(JSON.parse(raw), parts.scenario.adapter));
180
+ engine = new ScenarioEngine(parts.scenario.adapter, parseScenarioDocument(parseExactJson(raw), parts.scenario.adapter));
169
181
  engineRaw = raw;
170
182
  }
171
183
  return engine;
@@ -174,11 +186,13 @@ export function createPackFetch(parts, options = {}) {
174
186
  const decided = async (arrived) => {
175
187
  if (!parts.scenario)
176
188
  return api(arrived);
177
- // the body is read once and the request made again from its bytes: a served request's body cloned (for the turn's
178
- // context) and then forwarded tees a stream whose second branch a Bun server never finishes, and every turn hung
179
- // (measured on merge served with --scenario: no answer in 8 s, matched or not; t_c0279b69)
189
+ // the body is read once and the request made again from its bytes, so the turn's context and the API each read their
190
+ // own. Merge served with --scenario once answered no turn in 8 s (t_c0279b69), and this change came with the cure;
191
+ // putting the earlier read back (the served request cloned for the context, then forwarded) does not reproduce the
192
+ // hang on its own (2026-10-01: merge's CLI with --scenario, and its life walked over HTTP: every turn answered), so
193
+ // what hung is UNEXPLAINED, and this is no proof of its cause
180
194
  const bytes = arrived.method === 'GET' || arrived.method === 'HEAD' ? undefined : await arrived.arrayBuffer();
181
- const request = new Request(arrived.url, { method: arrived.method, headers: arrived.headers, ...(bytes ? { body: bytes } : {}) });
195
+ const request = new Request(arrived.url, { method: arrived.method, headers: arrived.headers, signal: arrived.signal, ...(bytes ? { body: bytes } : {}) });
182
196
  const url = new URL(request.url);
183
197
  const matched = matchOperation(routes, request.method, url.pathname, url.searchParams, request.headers);
184
198
  if (!matched || !parts.scenario.operations.includes(matched.operation.id))
@@ -212,7 +226,7 @@ export function createPackFetch(parts, options = {}) {
212
226
  const answer = parts.doors?.[d.id];
213
227
  if (!answer)
214
228
  throw new Error(`${m.vendor}: the manifest declares the door ${d.id}, and semantics/doors.ts exports no ${d.id}`);
215
- return { decl: d, path: pathMatcher(d.path.startsWith('/_twin/') ? d.path : `/_twin${d.path.startsWith('/') ? '' : '/'}${d.path}`, false), answer };
229
+ return { decl: d, path: pathMatcher(doorPath(d.path), false), answer };
216
230
  });
217
231
  const screens = (m.screens ?? []).filter((s) => s.status === 'done' && parts.screens?.[s.id]).map((s) => {
218
232
  const hosts = [s.host, ...(s.hosts ?? [])].map(hostMatcher);
@@ -240,23 +254,52 @@ export function createPackFetch(parts, options = {}) {
240
254
  };
241
255
  // a context the kernel opens for what no surface operation names: a door, a screen, the clock, the board
242
256
  const open = (request, id, method, path, params) => contextFor(m, { request, operation: { id, method, path, class: method === 'GET' ? 'retrieve' : 'action' }, params }, scope);
257
+ const advanceClock = async (request) => {
258
+ if (parts.clock)
259
+ await runAsVendorMove(async () => parts.clock(await open(new Request(request.url, m.tenant ? { headers: request.headers } : {}), 'clock', 'POST', '/_twin/clock', {})));
260
+ };
243
261
  const refusedReadOnly = () => vendorError(m, m.readOnly);
244
262
  const prefix = m.pathPrefix ? new RegExp(`^(?:${m.pathPrefix})(?=/)`) : undefined;
263
+ const base = surface.basePath ?? '';
264
+ const baseAlias = m.basePathAlias && base ? new RegExp(`^(?:${m.basePathAlias})(?=/)`) : undefined;
245
265
  const hostPath = m.pathFromHost ? new RegExp(m.pathFromHost, 'i') : undefined;
246
266
  const hostParams = m.hostParams ? new RegExp(m.hostParams, 'i') : undefined;
247
- /** The request as its vendor routes it: duplicate slashes collapsed, the manifest's path prefix taken off, a host's
267
+ // each operation's spanning parameters, keyed by the operation and the parameter as the route compiles them (a whole
268
+ // segment's label whose name the surface or the manifest declares spanning), so one operation's spanning name never
269
+ // keeps another's slashes, nor a label that only part of a segment holds
270
+ const spanningNames = new Set(surface.spanning ?? []);
271
+ const spanningOf = new Set(surface.operations.flatMap((op) => ((op.basePath ?? base) + op.path).split('/').flatMap((seg) => {
272
+ const label = /^\{([^}]+)\}$/.exec(seg)?.[1];
273
+ return label !== undefined && spanningNames.has(label) ? [`${op.id}\u0000${label}`] : [];
274
+ })));
275
+ /** A path as the vendor routes it: the manifest's path prefix taken off, the spec's base in an alias's place, a host's
248
276
  * path label (pathFromHost) put in front. */
249
- const routed = (request) => {
250
- const url = new URL(request.url);
251
- let path = url.pathname.replace(/\/{2,}/g, '/');
252
- // a prefix's named groups (Jira's `/ex/jira/(?<cloudId>[^/]+)`) and the host's (E2B's envd at
253
- // `49983-(?<sandboxID>…).e2b.app`) join the operation's parameters
254
- const groups = { ...(prefix?.exec(path)?.groups ?? {}), ...(hostParams?.exec(hostOf(request))?.groups ?? {}) };
277
+ const rewritten = (pathname, host) => {
278
+ let path = pathname;
255
279
  if (prefix)
256
280
  path = path.replace(prefix, '') || '/';
257
- const label = hostPath?.exec(hostOf(request))?.[1];
281
+ // a base the vendor serves as its own: the spec's base in its place (a path already under the spec's base stays)
282
+ if (baseAlias && !(path === base || path.startsWith(`${base}/`)))
283
+ path = path.replace(baseAlias, base);
284
+ const label = hostPath?.exec(host)?.[1];
258
285
  if (label)
259
286
  path = `/${label}${path === '/' ? '' : path}`;
287
+ return path;
288
+ };
289
+ /** The request as its vendor routes it: duplicate slashes collapsed, unless the rewritten path matches an operation
290
+ * through one of that operation's spanning parameters (the surface's and the manifest's), whose value keeps its
291
+ * slashes; then rewritten. */
292
+ const routed = (request) => {
293
+ const url = new URL(request.url);
294
+ const host = hostOf(request);
295
+ const kept = rewritten(url.pathname, host);
296
+ const matched = matchOperation(routes, request.method, kept);
297
+ const spanning = matched !== undefined && Object.keys(matched.params).some((name) => spanningOf.has(`${matched.operation.id}\u0000${name}`));
298
+ const source = spanning ? url.pathname : url.pathname.replace(/\/{2,}/g, '/');
299
+ // a prefix's named groups (Jira's `/ex/jira/(?<cloudId>[^/]+)`) and the host's (E2B's envd at
300
+ // `49983-(?<sandboxID>…).e2b.app`) join the operation's parameters
301
+ const groups = { ...(prefix?.exec(source)?.groups ?? {}), ...(hostParams?.exec(host)?.groups ?? {}), ...Object.fromEntries(Object.entries(m.headerParams ?? {}).flatMap(([param, header]) => { const value = request.headers.get(header); return value === null ? [] : [[param, value]]; })) };
302
+ const path = spanning ? kept : rewritten(source, host);
260
303
  if (path === url.pathname && !Object.keys(groups).length)
261
304
  return request;
262
305
  // the path the client sent, which a signature over the request (SigV4's canonical URI) covers
@@ -271,6 +314,8 @@ export function createPackFetch(parts, options = {}) {
271
314
  };
272
315
  const rootServes = (method, path) => Boolean(matchOperation(routes, method, path));
273
316
  const lane = m.lanes ? laneRouter(m.vendor, m.lanes, parts.lanes ?? {}, rootServes) : undefined;
317
+ // Inspect lane-owned World doors directly, without routing them back through the vendor gateway.
318
+ const laneDoor = (request, path) => laneDoors(parts.lanes ?? {}, request, path);
274
319
  // at a World's place, a page's asset or upload on another of the pack's content hosts is `<base>/@<host>/<path>`
275
320
  // (architecture, "A page at a World's place"): answered by the built content screen that names that host exactly,
276
321
  // routed from it, and by nothing else; a request naming no such host is general routing's
@@ -341,7 +386,7 @@ export function createPackFetch(parts, options = {}) {
341
386
  if (!address || !contentHosts.includes(address.host))
342
387
  return undefined;
343
388
  const readable = await prepared(arrived);
344
- return readable ? atContentHost(readable) : undecodable(arrived);
389
+ return readable instanceof Response ? readable : readable ? atContentHost(readable) : undecodable(arrived);
345
390
  };
346
391
  const fetch = async (arrived) => {
347
392
  // the discovery door is the pack's own, whichever lane would take its path
@@ -362,10 +407,14 @@ export function createPackFetch(parts, options = {}) {
362
407
  const own = await answerContent(arrived);
363
408
  if (own)
364
409
  return own;
365
- const toLane = discovery ? undefined : lane?.(arrived);
410
+ // Root World doors belong to the pack at every routed host, including a lane's host.
411
+ const rootDoor = doors.some((d) => d.decl.method.toUpperCase() === arrived.method && d.path(asked));
412
+ const toLane = discovery || rootDoor ? undefined : lane?.(arrived);
366
413
  if (toLane)
367
414
  return toLane(arrived);
368
415
  const readable = await prepared(arrived);
416
+ if (readable instanceof Response)
417
+ return readable;
369
418
  if (!readable)
370
419
  return undecodable(arrived);
371
420
  const incoming = routed(readable);
@@ -376,40 +425,48 @@ export function createPackFetch(parts, options = {}) {
376
425
  const readOnly = (options.readOnly ?? false) || isReadOnlyRequest(request);
377
426
  if (request.method === 'GET' && path === '/twin' && m.discovery) {
378
427
  const d = m.discovery;
428
+ const discoveryDoors = [...(m.doors ?? []), ...(m.machines ? [{ id: 'machine-pool', method: 'POST', path: '/_twin/machine-pool', note: 'Enroll the World execution pool: { kind: light | docker | none | fake, images?: { image: { context, command?, runtime? } } }.' }] : [])];
379
429
  // the workspaces a person can be shown (Viewing a World): each built workspace screen's id and path
380
- const shown = workspaces().length ? { screens: workspaces() } : {};
430
+ const laneDiscovery = await laneDoor(request, '/twin');
431
+ const shown = { ...(workspaces().length ? { screens: workspaces() } : {}), ...(Object.keys(laneDiscovery).length ? { lanes: laneDiscovery } : {}) };
432
+ const identity = d.identity ?? (m.auth?.held ? 'Authenticate as the vendor does, using a credential issued in this World; unknown credentials are refused.' : undefined);
381
433
  // a model vendor's: its state, and what its scenario scripts, with the scenario's live counts
382
434
  if (parts.scenario && d.behavior) {
383
- return Response.json({ ...shown, ...twinManifest({
384
- vendor: m.vendor, twinOf: d.twinOf,
385
- stateSentence: `Stateful: it stores ${d.stores}. Create state through the vendor's OWN API with the real SDK or plain fetch pointed here.`,
386
- behaviorSentence: d.behavior, exampleHandler: d.exampleHandler ?? null, ...(engineOf() ? { engine: engineOf() } : {}),
387
- }) });
435
+ const body = twinManifest({
436
+ vendor: m.vendor, twinOf: d.twinOf,
437
+ stateSentence: `Stateful: it stores ${d.stores}. Create state through the vendor's OWN API with the real SDK or plain fetch pointed here${discoveryDoors.length ? "; what the vendor does on its own pages (not its API) is a door of the World, listed under doors" : ''}.`,
438
+ behaviorSentence: d.behavior, exampleHandler: d.exampleHandler ?? null, ...(engineOf() ? { engine: engineOf() } : {}),
439
+ });
440
+ const declared = Object.fromEntries(discoveryDoors.map((door) => [`${door.method} ${doorPath(door.path)}`, door.note ?? 'a door of the World']));
441
+ return Response.json({ ...shown, ...body, program: { ...body.program, ...(identity ? { identity } : {}) }, doors: { ...body.doors, ...declared } });
388
442
  }
389
- return Response.json({ ...statefulTwinManifest({ vendor: m.vendor, twinOf: d.twinOf, stores: d.stores, ...(d.identity ? { identity: d.identity } : {}), ...(d.notes ? { notes: d.notes } : {}) }), ...shown });
443
+ return Response.json({ ...statefulTwinManifest({ vendor: m.vendor, twinOf: d.twinOf, stores: d.stores, ...(identity ? { identity } : {}), ...(d.behavior ? { behavior: d.behavior } : {}), ...(d.notes ? { notes: d.notes } : {}), ...(discoveryDoors.length ? { doors: discoveryDoors.map((door) => ({ ...door, path: doorPath(door.path) })) } : {}) }), ...shown });
390
444
  }
391
445
  // the scenario's handlers with their match counts, and the recent misses
392
- if (request.method === 'GET' && path === '/twin/scenario' && parts.scenario)
393
- return Response.json(engineOf()?.status() ?? { vendor: m.vendor, handlers: [], misses: 0, recentMisses: [] });
446
+ if (request.method === 'GET' && path === '/twin/scenario') {
447
+ const lanes = await laneDoor(request, '/twin/scenario');
448
+ if (parts.scenario || Object.keys(lanes).length)
449
+ return Response.json({ ...(engineOf()?.status() ?? { vendor: m.vendor, handlers: [], misses: 0, recentMisses: [] }), ...(Object.keys(lanes).length ? { lanes } : {}) });
450
+ }
394
451
  // the vendor's own moves, not the caller's: its context carries none of the request's headers (a Stripe-Account
395
452
  // header would make a payout time makes the caller's), but a tenant's, when the vendor keeps tenants apart
396
- if (parts.clock)
397
- await runAsVendorMove(async () => parts.clock(await open(new Request(request.url, m.tenant ? { headers: request.headers } : {}), 'clock', 'POST', '/_twin/clock', {})));
453
+ await advanceClock(request);
398
454
  if (path.startsWith('/_twin/')) {
399
455
  // the World's machine pool, enrolled by the kernel for a vendor that runs images (machines.ts)
400
456
  if (m.machines && path === '/_twin/machine-pool' && request.method === 'POST') {
401
457
  if (readOnly)
402
458
  return refusedReadOnly();
403
- let kind;
459
+ let enrollment = {};
404
460
  try {
405
- kind = JSON.parse(await request.clone().text()).kind;
406
- }
407
- catch {
408
- kind = undefined;
461
+ enrollment = parseExactJson(await request.clone().text());
409
462
  }
463
+ catch { }
464
+ const kind = enrollment.kind;
410
465
  if (!POOL_KINDS.includes(kind))
411
466
  return Response.json({ message: `kind must be one of ${POOL_KINDS.join(', ')}` }, { status: 400 });
412
- await applyTwinWrite(m.service, { operation: 'machine_pool.enroll', subjectType: MACHINE_POOL, subjectId: 'pool', fields: { kind }, occurredAt: (await open(request, 'machine-pool', 'POST', '/_twin/machine-pool', {})).occurredAt, actor: { kind: 'system' } }, options.root);
467
+ await applyTwinWrite(m.service, { operation: 'machine_pool.enroll', subjectType: MACHINE_POOL, subjectId: 'pool', fields: { kind, ...(kind === 'fake' && Array.isArray(enrollment.httpReplies) ? { httpReplies: enrollment.httpReplies } : {}), ...(kind === 'light' ? { images: enrollment.images ?? {} } : {}) }, occurredAt: (await open(request, 'machine-pool', 'POST', '/_twin/machine-pool', {})).occurredAt, actor: { kind: 'system' } }, options.root);
468
+ if (kind === 'fake')
469
+ resetFakePool(m.service, options.root);
413
470
  return Response.json({ kind }, { status: 201 });
414
471
  }
415
472
  for (const d of doors) {
@@ -455,12 +512,34 @@ export function createPackFetch(parts, options = {}) {
455
512
  return refusedReadOnly();
456
513
  return byPath.s.answer(await open(request, byPath.s.decl.id, request.method, byPath.s.decl.path, { ...(byPath.onHost?.params ?? {}), ...byPath.hit.params }));
457
514
  }
515
+ for (const route of m.machineRoutes ?? []) {
516
+ const host = request.headers.get('x-volter-twin-original-host') ?? new URL(request.url).hostname;
517
+ const match = new RegExp(route.host).exec(host);
518
+ if (!match)
519
+ continue;
520
+ const ctx = await open(request, 'machine.traffic', request.method, url.pathname, match.groups ?? {});
521
+ const field = (row, path) => path.split('.').reduce((value, key) => value && typeof value === 'object' ? value[key] : undefined, row);
522
+ const fill = (value, row = {}) => value.replace(/\{([^}]+)\}/g, (_, key) => String(match.groups?.[key] ?? field(row, key) ?? ''));
523
+ const row = ctx.rowsRaw(route.resource).find(row => Object.entries(route.where).every(([key, value]) => String(field(row, key)) === fill(value)));
524
+ if (!row)
525
+ return new Response('Guest is unavailable', { status: 503 });
526
+ try {
527
+ return await ctx.machines.request(String(field(row, route.name)), Number(typeof route.port === 'string' ? fill(route.port, row) : route.port), request);
528
+ }
529
+ catch {
530
+ return new Response('Guest is unavailable', { status: 503 });
531
+ }
532
+ }
458
533
  if (!parts.around)
459
534
  return encoded(m, request, await decided(request));
460
- const matched = matchOperation(routes, request.method, url.pathname, url.searchParams, request.headers);
461
- const operation = matched?.operation ?? { id: 'unmatched', method: request.method, path: url.pathname, class: request.method === 'GET' ? 'retrieve' : 'action' };
462
- const ctx = await contextFor(m, { request: request.clone(), operation, params: matched?.params ?? {} }, scope);
463
- return encoded(m, request, await parts.around(ctx, (rewritten) => decided(rewritten ?? request)));
535
+ // The front reads a context before forwarding (possibly with new headers). Materialize a transport body before
536
+ // those independent reads, rather than chaining tees of the incoming stream through the front and the scenario.
537
+ const bytes = request.method === 'GET' || request.method === 'HEAD' ? undefined : await request.arrayBuffer();
538
+ const buffered = new Request(request.url, { method: request.method, headers: request.headers, signal: request.signal, ...(bytes ? { body: bytes } : {}) });
539
+ const matched = matchOperation(routes, buffered.method, url.pathname, url.searchParams, buffered.headers);
540
+ const operation = matched?.operation ?? { id: 'unmatched', method: buffered.method, path: url.pathname, class: buffered.method === 'GET' ? 'retrieve' : 'action' };
541
+ const ctx = await contextFor(m, { request: buffered.clone(), operation, params: matched?.params ?? pathParams(routes, url.pathname) }, scope);
542
+ return encoded(m, buffered, await parts.around(ctx, (rewritten) => decided(rewritten ?? buffered)));
464
543
  };
465
544
  // the request's id is the correlation of every entry it appends (runtime contract D3), minted here, always: it is the
466
545
  // group a perform sends as one call (the real-system adapters, "Perform"). Under `auto` the group is performed once
@@ -508,12 +587,20 @@ export function createPackFetch(parts, options = {}) {
508
587
  for (const d of m.sockets ?? [])
509
588
  if (!parts.sockets?.[d.id])
510
589
  throw new Error(`${m.vendor}: the manifest declares the socket ${d.id}, and semantics/sockets.ts exports no ${d.id}`);
511
- const upgrade = m.sockets?.length ? socketUpgrade(m.service, options.root, m.sockets, parts.sockets, (request, d) => open(request, `socket:${d.id}`, 'GET', d.path, {}), hostOf, (request) => new URL(routed(request).url).pathname,
590
+ const ownUpgrade = m.sockets?.length ? socketUpgrade(m.service, options.root, m.sockets, parts.sockets, (request, d) => open(request, `socket:${d.id}`, 'GET', d.path, {}), hostOf, (request) => new URL(routed(request).url).pathname,
512
591
  // a turn a session speaks (a voice agent's reply) is the World's scenario's, as a turn over HTTP is
513
592
  async (asked) => engineOf()?.serve(asked)) : undefined;
514
- // what serves each operation: the pack's own, and each lane's
515
- const owners = () => ({ ...api.owners(), ...lanesOwners(parts.lanes ?? {}) });
516
- return derivedRequestScopes(m, Object.assign(served, { owners, serves, workspaces, boards: Boolean(parts.board), draws: drawsUrl, contentHosts, ...(upgrade ? { upgrade } : {}) }));
593
+ const upgrade = laneUpgrades(parts.lanes ?? {}, ownUpgrade);
594
+ // what serves each operation: the pack's own, and each lane's, each unit's under its own name
595
+ const ownersByUnit = () => ({
596
+ '': {
597
+ ...((surface.format === 'command-reply' || surface.format === 'command-table' && m.descriptor?.transport === 'raw-tcp') ? Object.fromEntries((surface.commands ?? []).map((c) => [c.id, parts.around && !m.unmodeled?.includes(c.id) ? 'handler' : 'gap'])) : api.owners()),
598
+ ...Object.fromEntries((parts.graphql?.operations ?? []).map((op) => [op.id, `${op.kind === 'query' ? 'Query' : 'Mutation'}.${op.field}` in (parts.graphql?.resolvers ?? {}) ? 'handler' : 'gap'])),
599
+ },
600
+ ...lanesOwners(parts.lanes ?? {}),
601
+ });
602
+ const owners = () => flatOwners(ownersByUnit());
603
+ return derivedRequestScopes(m, Object.assign(served, { owners, ownersByUnit, serves, advanceClock, workspaces, boards: Boolean(parts.board), maxRequestBodySize: m.descriptor?.maxRequestBodySize, draws: drawsUrl, contentHosts, ...(upgrade ? { upgrade } : {}) }), options.readOnly);
517
604
  }
518
605
  /** The vendor's gateway over its lanes: the lane a request goes to (a door to the lane that declares it, then the first
519
606
  * route whose conditions all hold, then the default), behind the gateway's CORS; undefined when none takes it. */
@@ -568,13 +655,52 @@ function laneRouter(vendor, decl, lanes, rootServes = () => false) {
568
655
  }
569
656
  /** A vendor whose every API is a lane (Cloudflare's API v4 and R2, AWS's services), served from its manifest: the
570
657
  * discovery door, then its lanes as its gateway sends them; a request no lane takes is the vendor's not-found. */
571
- /** What serves each of a vendor's lanes' operations (a handler, the core, or the gap), as one map. */
572
- const lanesOwners = (lanes) => Object.assign({}, ...Object.values(lanes).map((l) => l.fetch.owners?.() ?? {}));
658
+ /** Each lane's answer at one of its World doors (`/twin`, `/twin/scenario`), by lane, read from the lane directly rather
659
+ * than routed back through the vendor's front: a vendor's discovery holds its lanes' (their doors, their scripts). */
660
+ async function laneDoors(lanes, request, path) {
661
+ const entries = await Promise.all(Object.entries(lanes).map(async ([name, part]) => {
662
+ const url = new URL(request.url);
663
+ url.pathname = path;
664
+ url.search = '';
665
+ const answer = await part.fetch(new Request(url, { headers: request.headers, signal: request.signal }));
666
+ return answer.ok ? [name, await answer.json()] : undefined;
667
+ }));
668
+ return Object.fromEntries(entries.filter((entry) => entry !== undefined));
669
+ }
670
+ /** What serves each of a vendor's lanes' operations (a handler, the core, or the gap), by lane: a lane's operation is the
671
+ * lane's own, so an id it shares with its root or another lane (Clerk's Backend and Frontend APIs both name
672
+ * `ListOrganizationMemberships`) keeps the lane's own owner, and a lane's gap stays a gap whoever else serves the id. */
673
+ const lanesOwners = (lanes) => Object.fromEntries(Object.entries(lanes).map(([name, l]) => [name, l.fetch.owners?.() ?? {}]));
674
+ /** A vendor's owners as one map, for its breadth: its own API's operations by id, a lane's as `<lane>:<id>`. */
675
+ const flatOwners = (byUnit) => Object.fromEntries(Object.entries(byUnit).flatMap(([unit, map]) => Object.entries(map).map(([id, owner]) => [unit ? `${unit}:${id}` : id, owner])));
573
676
  /** The workspaces a vendor's lanes draw, as one list. */
574
677
  const lanesWorkspaces = (lanes) => Object.values(lanes).flatMap((l) => l.fetch.workspaces?.() ?? []);
678
+ /** Keep each upgraded peer on the vendor or lane engine that accepted its opening request. */
679
+ function laneUpgrades(lanes, own) {
680
+ const choices = [own, ...Object.values(lanes).map(lane => lane.fetch.upgrade)].filter((choice) => choice !== undefined);
681
+ if (choices.length === 0)
682
+ return undefined;
683
+ if (choices.length === 1)
684
+ return choices[0];
685
+ const held = new WeakMap();
686
+ const select = (request) => choices.find(choice => choice.accepts(request));
687
+ return {
688
+ accepts: request => select(request) !== undefined,
689
+ protocol: request => select(request)?.protocol?.(request),
690
+ open(peer, request) { const selected = select(request); if (selected) {
691
+ held.set(peer, selected);
692
+ selected.open(peer, request);
693
+ } },
694
+ message(peer, data) { return held.get(peer)?.message(peer, data); },
695
+ close(peer) { const selected = held.get(peer); held.delete(peer); selected?.close(peer); },
696
+ };
697
+ }
575
698
  export function createVendorFetch(manifest, lanes) {
699
+ const upgrade = laneUpgrades(lanes);
576
700
  const lane = laneRouter(manifest.vendor, manifest.lanes, lanes);
577
701
  return Object.assign(async (request) => {
702
+ for (const part of Object.values(lanes))
703
+ await part.fetch.advanceClock?.(request);
578
704
  const path = new URL(request.url).pathname.replace(/\/+$/, '') || '/';
579
705
  // the vendor's board is the frames of the lanes that lay one out, each drawn when any lane's screen takes its url
580
706
  if (request.method === 'GET' && path === '/twin/board') {
@@ -595,9 +721,15 @@ export function createVendorFetch(manifest, lanes) {
595
721
  if (request.method === 'GET' && path === '/twin' && manifest.discovery) {
596
722
  // the vendor's screens are its lanes' (a dashboard drawn by one lane is the vendor's)
597
723
  const screens = lanesWorkspaces(lanes);
598
- return Response.json({ ...statefulTwinManifest({ vendor: manifest.vendor, ...manifest.discovery }), ...(screens.length ? { screens } : {}) });
724
+ const laneDiscovery = await laneDoors(lanes, request, '/twin');
725
+ return Response.json({ ...statefulTwinManifest({ vendor: manifest.vendor, ...manifest.discovery }), ...(screens.length ? { screens } : {}), ...(Object.keys(laneDiscovery).length ? { lanes: laneDiscovery } : {}) });
726
+ }
727
+ if (request.method === 'GET' && path === '/twin/scenario') {
728
+ const laneScenarios = await laneDoors(lanes, request, '/twin/scenario');
729
+ if (Object.keys(laneScenarios).length)
730
+ return Response.json({ vendor: manifest.vendor, lanes: laneScenarios });
599
731
  }
600
732
  const to = lane(request);
601
733
  return to ? to(request) : Response.json({ error: `${manifest.vendor}: no lane serves ${request.method} ${path}` }, { status: 404 });
602
- }, { owners: () => lanesOwners(lanes), workspaces: () => lanesWorkspaces(lanes) });
734
+ }, { maxRequestBodySize: manifest.descriptor?.maxRequestBodySize, owners: () => flatOwners(lanesOwners(lanes)), ownersByUnit: () => lanesOwners(lanes), workspaces: () => lanesWorkspaces(lanes), ...(upgrade ? { upgrade } : {}) });
603
735
  }
@@ -140,6 +140,7 @@ export type HostRule = ({
140
140
  hostPattern: string;
141
141
  }) & {
142
142
  pathPattern?: string;
143
+ demandPathPattern?: string | false;
143
144
  key?: string;
144
145
  exclude?: true;
145
146
  };
@@ -171,6 +172,8 @@ export type TwinPack = {
171
172
  rateBudget?: RateBudgetDeclaration;
172
173
  emitter?: TwinEmitter;
173
174
  serveExport?: string;
175
+ /** Declared HTTP transport cap, in bytes; the serve seam and World fronts honor it. */
176
+ maxRequestBodySize?: number;
174
177
  adoption?: {
175
178
  sdks?: string[];
176
179
  pypi?: string[];
@@ -187,6 +190,9 @@ export type TwinPack = {
187
190
  usage: 'build' | 'deployment';
188
191
  }>;
189
192
  };
193
+ /** Why no client case is owed though `adoption.sdks` names npm clients: the vendor maintains no official SDK, or the
194
+ * demand's applications use none (architecture, "The descriptor"; `conform`'s client check reads it). */
195
+ clientCasesNone?: string;
190
196
  hosts?: HostRule[];
191
197
  hostsNone?: string;
192
198
  hostsClaimed?: {
@@ -202,7 +208,7 @@ export type TwinPack = {
202
208
  /** The door that issues the application the credentials the twin will accept (a key made on the vendor's dashboard,
203
209
  * and whatever names it: a database's URL, a project's id), and the env names it fills, each from a field of the
204
210
  * answer: `init` writes `$issue:<service>` for each, and `up`, once this twin is running, POSTs the body to the door
205
- * and sets each name to its field. A twin that holds its keys (refusing any it
211
+ * and sets each name to its field (`file:<field>` materializes one file; `directory:<field>` a relative-file map). A twin that holds its keys (refusing any it
206
212
  * did not issue) declares one, so a World's applications hold keys it issued rather than fixtures it refuses. */
207
213
  credentialDoor?: {
208
214
  path: string;
@@ -117,12 +117,29 @@ beside = {}) {
117
117
  if (hand.length)
118
118
  throw new Error(`${manifest.vendor}: the descriptor declares ${hand.join(', ')} by hand; the kernel derives them from the manifest (architecture, "The real-system adapters")`);
119
119
  const pack = { vendor: manifest.vendor, ...manifest.descriptor, ...(manifest.rateBudget ? { rateBudget: manifest.rateBudget } : {}) };
120
- // a pack with no vendor-backed half says why, and derives no adapters
121
- if (manifest.vendorBacked?.none)
120
+ // a pack with no vendor-backed half says why, and derives no adapters; one whose own surface has none beside lanes
121
+ // that do derives its lanes' adapters, its own writes settled as the World's (`unsent`)
122
+ const live = Object.fromEntries(Object.entries(beside).filter(([, l]) => !l.manifest.vendorBacked?.none));
123
+ if (manifest.vendorBacked?.none && !Object.keys(live).length)
122
124
  return { ...pack, vendorBacked: { none: manifest.vendorBacked.none } };
123
125
  if (!surface)
124
126
  return pack;
125
- const lanes = 'operations' in surface ? undefined : surface;
127
+ // the unit's own surface: its operations, or a command table (a vendor that carries Redis over HTTP: architecture,
128
+ // "Other wires"), which names no operation a derived adapter performs; anything else is a map of lanes
129
+ const ownSurface = 'operations' in surface || 'commands' in surface;
130
+ if (manifest.vendorBacked?.none && ownSurface) {
131
+ const own = new Set((surface.operations ?? []).map((o) => o.id));
132
+ // a command table's every write is the unit's own (no operation of it is performed)
133
+ const commandTable = !('operations' in surface);
134
+ const why = manifest.vendorBacked.none;
135
+ const references = [manifest, ...Object.values(beside).map((l) => l.manifest)].flatMap(derivedReferences);
136
+ return {
137
+ ...pack,
138
+ stateSystem: { ...deriveVendorStateSystem(manifest, live), unsent: (input) => (input && typeof input.lane !== 'string' && (commandTable || own.has(String(input.operationId))) ? why : undefined) },
139
+ ...(references.length ? { references } : {}),
140
+ };
141
+ }
142
+ const lanes = ownSurface ? undefined : surface;
126
143
  const units = lanes ? Object.values(lanes).map((l) => l.manifest) : [manifest, ...Object.values(beside).map((l) => l.manifest)];
127
144
  const references = units.flatMap(derivedReferences);
128
145
  return {
@@ -0,0 +1 @@
1
+ export declare function privateTransportKey(namespace: string): string;
@@ -0,0 +1,11 @@
1
+ // Process-local ingress capabilities for byte-stream fronts using an internal request seam.
2
+ // Lazy: importing the pack contract creates no key and opens no process handle.
3
+ const keys = new Map();
4
+ export function privateTransportKey(namespace) {
5
+ let key = keys.get(namespace);
6
+ if (!key) {
7
+ key = crypto.randomUUID();
8
+ keys.set(namespace, key);
9
+ }
10
+ return key;
11
+ }
@@ -87,7 +87,7 @@ function writeScalar(w, type, v) {
87
87
  break;
88
88
  case 'fixed32':
89
89
  case 'sfixed32':
90
- w.fixed(Number(v), 4);
90
+ w.fixed(BigInt(v), 4);
91
91
  break;
92
92
  case 'float':
93
93
  w.fixed(Number(v), 4, true);
@@ -228,7 +228,7 @@ function readScalar(r, type) {
228
228
  case 'uint32': return Number(BigInt.asUintN(32, r.varint()));
229
229
  case 'int64': return String(BigInt.asIntN(64, r.varint()));
230
230
  case 'uint64': return String(BigInt.asUintN(64, r.varint()));
231
- case 'sint32': return Number(unzigzag(r.varint()));
231
+ case 'sint32': return Number(BigInt.asIntN(32, unzigzag(r.varint())));
232
232
  case 'sint64': return String(unzigzag(r.varint()));
233
233
  case 'bool': return r.varint() !== 0n;
234
234
  case 'fixed64': return String(new DataView(r.take(8).slice().buffer).getBigUint64(0, true));
@@ -291,7 +291,10 @@ export function decodeMessage(schema, type, bytes) {
291
291
  const out = {};
292
292
  const r = new Reader(bytes);
293
293
  while (!r.done) {
294
- const key = Number(r.varint());
294
+ const rawKey = r.varint();
295
+ if (rawKey > 0xffffffffn)
296
+ throw new Error('protobuf: field tag exceeds 32 bits');
297
+ const key = Number(rawKey);
295
298
  const number = key >>> 3;
296
299
  const wire = key & 7;
297
300
  const f = byNumber.get(number);
@@ -304,7 +307,10 @@ export function decodeMessage(schema, type, bytes) {
304
307
  let k;
305
308
  let v;
306
309
  while (!entry.done) {
307
- const ek = Number(entry.varint());
310
+ const rawKey = entry.varint();
311
+ if (rawKey > 0xffffffffn)
312
+ throw new Error('protobuf: map field tag exceeds 32 bits');
313
+ const ek = Number(rawKey);
308
314
  if ((ek >>> 3) === 1)
309
315
  k = readValue(schema, entry, { type: f.map.key, kind: 'scalar' }, ek & 7);
310
316
  else if ((ek >>> 3) === 2)
@@ -86,6 +86,13 @@ export type RateBudgetDeclaration = {
86
86
  * review, and the ceiling is the one number that can cost days if it is wrong.
87
87
  */
88
88
  reason: string;
89
+ /** The vendor's documented allowance, in calls a minute, and the page that documents it, which the pack cites on a
90
+ * `// source:` line (checked like every other vendor fact): required of a budget that admits more than the fallback
91
+ * (`scripts/rate-budget-check.ts`). */
92
+ allowance?: {
93
+ perMinute: number;
94
+ source: string;
95
+ };
89
96
  };
90
97
  /**
91
98
  * A declaration bound to the vendor it governs, with every pattern already compiled. The `RegExp`s
@@ -94,7 +101,7 @@ export type RateBudgetDeclaration = {
94
101
  * pattern. (Declarations are repo source, not user input — this is a performance fix, not a
95
102
  * sanitizer.)
96
103
  */
97
- export type RateBudgetPolicy = Required<Omit<RateBudgetDeclaration, 'rules'>> & {
104
+ export type RateBudgetPolicy = Required<Omit<RateBudgetDeclaration, 'rules' | 'allowance'>> & Pick<RateBudgetDeclaration, 'allowance'> & {
98
105
  vendor: string;
99
106
  rules: RateBudgetWeightRule[];
100
107
  /** `compiled[i]` is `rules[i].match`, compiled. Same length, same order. */
@@ -248,6 +248,7 @@ function normalize(vendor, decl) {
248
248
  return {
249
249
  vendor,
250
250
  reason: decl.reason,
251
+ ...(decl.allowance ? { allowance: { ...decl.allowance } } : {}),
251
252
  windowMs,
252
253
  ceiling,
253
254
  burstCeiling,