@volter/twin-tunnel 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1770 @@
1
+ import { mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { createHash } from 'node:crypto';
3
+ import { hostname, tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { listActions, projectResources, worldPaths } from '@volter/world-core';
6
+ import { checkCapabilities, type CapabilityReport, type CapabilitySpec, verifyBoundary } from '@volter/world-tooling';
7
+ import { createTunnelTwinJwt, createTunnelTwinServer, tunnelControlPathIsReserved } from './tunnel-server.ts';
8
+ import { handleTunnelRelayMessage, handleTunnelTwinRequest, markTunnelDisconnected, persistTunnelRelayRegistration, prepareTunnelRelayRegistration, TUNNEL_PROTOCOL_MESSAGE_TYPES, type RelaySession } from './tunnel-twin.ts';
9
+ import { checkTunnelConformance } from './tunnel-conformance.ts';
10
+ import { liveTunnelExecute, mapTunnelRelay, syncTunnelFromReal } from './tunnel-connector.ts';
11
+ import { TunnelBudget, TunnelBudgetError, TUNNEL_BUDGET_CEILING, TUNNEL_CALL_WEIGHTS } from './tunnel-budget.ts';
12
+
13
+ const done = (id: string, area: string, title: string, dimension: CapabilitySpec['dimension'], tier: CapabilitySpec['tier'], verify: CapabilitySpec['verify']): CapabilitySpec =>
14
+ ({ id, area, title, dimension, tier, expected: 'done', verify });
15
+ const todo = (id: string, area: string, title: string, dimension: CapabilitySpec['dimension'], tier: CapabilitySpec['tier']): CapabilitySpec =>
16
+ ({ id, area, title, dimension, tier, expected: 'todo' });
17
+
18
+ const AT = '2026-01-01T00:00:00.000Z';
19
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
20
+ async function withRoot(fn: (root: string) => Promise<boolean>): Promise<boolean> {
21
+ const root = mkdtempSync(join(tmpdir(), 'tunnel-cap-'));
22
+ try { return await verifyBoundary('tunnel.withRoot', () => fn(root)); }
23
+ finally { rmSync(root, { recursive: true, force: true }); }
24
+ }
25
+
26
+ async function quick(root: string, over: Partial<{ method: string; path: string; readOnly: boolean }> = {}) {
27
+ return handleTunnelTwinRequest({ method: over.method ?? 'POST', path: over.path ?? '/tunnel', readOnly: over.readOnly, root, occurredAt: AT });
28
+ }
29
+
30
+ function nextSocketMessage(socket: WebSocket, type: string, timeoutMs = 3_000): Promise<Record<string, any>> {
31
+ return new Promise((resolve, reject) => {
32
+ const timer = setTimeout(() => { cleanup(); reject(new Error(`timed out waiting for ${type}`)); }, timeoutMs);
33
+ const onMessage = (event: MessageEvent) => {
34
+ const message = JSON.parse(String(event.data)) as Record<string, any>;
35
+ if (message.type !== type) return;
36
+ cleanup(); resolve(message);
37
+ };
38
+ const cleanup = () => { clearTimeout(timer); socket.removeEventListener('message', onMessage); };
39
+ socket.addEventListener('message', onMessage);
40
+ });
41
+ }
42
+
43
+ function nextSocketOutcome(socket: WebSocket, types: string[], timeoutMs = 3_000): Promise<Record<string, any>> {
44
+ return new Promise((resolve, reject) => {
45
+ const timer = setTimeout(() => { cleanup(); reject(new Error(`timed out waiting for ${types.join('/')}`)); }, timeoutMs);
46
+ const onMessage = (event: MessageEvent) => {
47
+ const message = JSON.parse(String(event.data)) as Record<string, any>;
48
+ if (!types.includes(String(message.type))) return;
49
+ cleanup(); resolve(message);
50
+ };
51
+ const cleanup = () => { clearTimeout(timer); socket.removeEventListener('message', onMessage); };
52
+ socket.addEventListener('message', onMessage);
53
+ });
54
+ }
55
+
56
+ async function relayFrameOutcome(
57
+ control: Awaited<ReturnType<typeof openControl>>,
58
+ path: string,
59
+ frames: Array<Record<string, unknown>>,
60
+ ): Promise<{ kind: 'response'; status: number; body: string } | { kind: 'error'; error: string } | { kind: 'timeout' }> {
61
+ const aborter = new AbortController();
62
+ const requestFrame = nextSocketMessage(control.socket, 'request');
63
+ const observed = fetch(`${control.url}${path}`, { signal: aborter.signal }).then(async (response) => {
64
+ try { return { kind: 'response' as const, status: response.status, body: await response.text() }; }
65
+ catch (error) { return { kind: 'error' as const, error: String(error) }; }
66
+ }, (error) => ({ kind: 'error' as const, error: String(error) }));
67
+ const request = await requestFrame;
68
+ for (const frame of frames) control.socket.send(JSON.stringify({ ...frame, reqId: request.reqId }));
69
+ let timeout: ReturnType<typeof setTimeout> | undefined;
70
+ const outcome = await Promise.race([
71
+ observed,
72
+ new Promise<{ kind: 'timeout' }>((resolve) => { timeout = setTimeout(() => resolve({ kind: 'timeout' }), 500); }),
73
+ ]);
74
+ if (timeout) clearTimeout(timeout);
75
+ if (outcome.kind === 'timeout') aborter.abort();
76
+ return outcome;
77
+ }
78
+
79
+ async function openControl(relayUrl: string, tunnelId: string, options: { replace?: boolean; authRequired?: boolean } = {}) {
80
+ const socket = new WebSocket(`${relayUrl.replace(/^http/, 'ws')}/ws`);
81
+ const registered = nextSocketMessage(socket, 'registered');
82
+ await new Promise<void>((resolve, reject) => {
83
+ socket.addEventListener('open', () => resolve(), { once: true });
84
+ socket.addEventListener('error', () => reject(new Error('control socket failed')), { once: true });
85
+ });
86
+ socket.send(JSON.stringify({
87
+ type: 'register', tunnelId, secret: 'vt_fake_local', ...(options.replace ? { replace: true } : {}),
88
+ ...(options.authRequired !== undefined ? { authRequired: options.authRequired } : {}),
89
+ }));
90
+ const message = await registered;
91
+ return { socket, url: String(message.url), tunnelId: String(message.tunnelId) };
92
+ }
93
+
94
+ /**
95
+ * A relay, a registered control socket, and a REAL local WebSocket server — with the control
96
+ * socket bridging between them exactly as the owned client does.
97
+ *
98
+ * A HARNESS SHAPED AFTER `handleWsUpgrade`, not a reproduction of it — §9 was right to refuse
99
+ * the stronger word. What it does share with the vendor's client is everything the relay is
100
+ * judged on: dial the local server on `ws-upgrade` carrying the offered subprotocols, answer
101
+ * `ws-ready` when it opens and `ws-error` when it FAILS (a real listener, not a scripted one),
102
+ * strip the hop-by-hop handshake headers the client strips, forward local frames back as
103
+ * `ws-message` with the `binary` flag, and relay `ws-close`. What it does NOT reproduce, and
104
+ * does not need to because no assertion depends on it: the client's `x-forwarded-*`/`origin`
105
+ * re-stamping, its 15-second dial timeout, and `safeClose`'s FIN-not-RST teardown. Driving the
106
+ * twin over a genuine loopback WebSocket against a real local server is what makes these
107
+ * verifies transport proofs rather than assertions about the relay talking to itself.
108
+ *
109
+ * `mode` selects what the pretend client does with an upgrade: bridge it for real, hold `ws-ready`
110
+ * back (so the queueing behaviour is observable), or refuse it with `ws-error`.
111
+ */
112
+ async function openWsBridge(root: string, mode: 'bridge' | 'hold' | 'refuse' = 'bridge') {
113
+ const app = Bun.serve<{ path: string }>({
114
+ hostname: '127.0.0.1',
115
+ port: 0,
116
+ fetch(request, server) {
117
+ const url = new URL(request.url);
118
+ // A real local server negotiates the subprotocol it was offered; without that, the
119
+ // relay's own echo could look correct while nothing downstream honoured it.
120
+ const offered = (request.headers.get('sec-websocket-protocol') ?? '').split(',').map((p) => p.trim()).filter(Boolean);
121
+ return server.upgrade(request, {
122
+ ...(offered[0] ? { headers: { 'sec-websocket-protocol': offered[0] } } : {}),
123
+ data: { path: url.pathname + url.search },
124
+ }) ? undefined : new Response('expected websocket', { status: 426 });
125
+ },
126
+ websocket: {
127
+ message(ws, raw) {
128
+ // Text echoes with a marker; binary comes back REVERSED, so a verify can tell a genuine
129
+ // binary round trip from a text one that happened to survive.
130
+ if (typeof raw === 'string') ws.send(`echo:${ws.data.path}:${raw}`);
131
+ else ws.send(new Uint8Array([...Buffer.from(raw)].reverse()));
132
+ },
133
+ },
134
+ });
135
+ const relay = createTunnelTwinServer({ root });
136
+ const control = await openControl(relay.url, 'ws-bridge', { authRequired: false });
137
+ const locals = new Map<string, WebSocket>();
138
+ const frames: Array<Record<string, any>> = [];
139
+ const held: Array<Record<string, any>> = [];
140
+ control.socket.addEventListener('message', (event) => {
141
+ const message = JSON.parse(String(event.data)) as Record<string, any>;
142
+ frames.push(message);
143
+ if (message.type === 'ws-upgrade') {
144
+ if (mode === 'refuse') {
145
+ control.socket.send(JSON.stringify({ type: 'ws-error', connId: message.connId, error: 'ECONNREFUSED dialling local server' }));
146
+ return;
147
+ }
148
+ // The vendor's `handleWsUpgrade` reads `sec-websocket-protocol` off the frame's headers
149
+ // and passes it to the local dial as `protocols`; reproducing that is what makes the
150
+ // subprotocol assertion below a claim about the WHOLE path, not just the relay's 101.
151
+ const offered = String(message.headers?.['sec-websocket-protocol'] ?? '').split(',').map((p: string) => p.trim()).filter(Boolean);
152
+ const local = offered.length > 0
153
+ ? new WebSocket(`ws://127.0.0.1:${app.port}${message.path}`, offered)
154
+ : new WebSocket(`ws://127.0.0.1:${app.port}${message.path}`);
155
+ local.binaryType = 'arraybuffer';
156
+ // The client's REAL failure path: a local socket that errors reports `ws-error` rather
157
+ // than leaving the browser hanging. `refuse` mode scripts that answer without dialling;
158
+ // this is the same frame arriving from an actual failed dial.
159
+ local.addEventListener('error', () => {
160
+ if (locals.get(String(message.connId)) !== local) return;
161
+ locals.delete(String(message.connId));
162
+ control.socket.send(JSON.stringify({ type: 'ws-error', connId: message.connId, error: 'local websocket failed' }));
163
+ });
164
+ locals.set(String(message.connId), local);
165
+ local.addEventListener('open', () => {
166
+ if (mode === 'hold') { held.push(message); return; }
167
+ control.socket.send(JSON.stringify({ type: 'ws-ready', connId: message.connId }));
168
+ });
169
+ local.addEventListener('message', (localEvent) => {
170
+ const binary = typeof localEvent.data !== 'string';
171
+ const bytes = binary ? Buffer.from(localEvent.data as ArrayBuffer) : Buffer.from(String(localEvent.data), 'utf8');
172
+ control.socket.send(JSON.stringify({ type: 'ws-message', connId: message.connId, data: bytes.toString('base64'), binary }));
173
+ });
174
+ local.addEventListener('close', (closeEvent) => {
175
+ control.socket.send(JSON.stringify({ type: 'ws-close', connId: message.connId, code: closeEvent.code, reason: closeEvent.reason }));
176
+ locals.delete(String(message.connId));
177
+ });
178
+ return;
179
+ }
180
+ if (message.type === 'ws-message') {
181
+ const local = locals.get(String(message.connId));
182
+ const bytes = Buffer.from(String(message.data), 'base64');
183
+ if (local?.readyState === WebSocket.OPEN) local.send(message.binary === true ? new Uint8Array(bytes) : bytes.toString('utf8'));
184
+ return;
185
+ }
186
+ if (message.type === 'ws-close') {
187
+ const local = locals.get(String(message.connId));
188
+ if (local) { local.close(); locals.delete(String(message.connId)); }
189
+ }
190
+ });
191
+ return {
192
+ relay, control, app, frames, held, locals,
193
+ /** Release a held `ws-ready` — the "the local socket finally came up" moment. */
194
+ release() { for (const message of held.splice(0)) control.socket.send(JSON.stringify({ type: 'ws-ready', connId: message.connId })); },
195
+ /**
196
+ * Open a BROWSER socket through the tunnel and return it with the `connId` the relay
197
+ * announced for it.
198
+ *
199
+ * It waits for the `ws-upgrade` FRAME, not just for the browser handshake: the browser's
200
+ * `open` fires before the relay's own socket-open handler has sent the frame, so reading
201
+ * `frames` straight after the handshake is a race that reports "no upgrade" on a bridge that
202
+ * is about to work.
203
+ */
204
+ async visitor(path: string, protocols: string[] = []): Promise<{ socket: WebSocket; upgrade: Record<string, any> }> {
205
+ const before = frames.filter((frame) => frame.type === 'ws-upgrade').length;
206
+ const socket = protocols.length > 0
207
+ ? new WebSocket(`${control.url.replace(/^http/, 'ws')}${path}`, protocols)
208
+ : new WebSocket(`${control.url.replace(/^http/, 'ws')}${path}`);
209
+ socket.binaryType = 'arraybuffer';
210
+ await new Promise<void>((resolve, reject) => {
211
+ const timer = setTimeout(() => reject(new Error('visitor websocket did not open')), 3_000);
212
+ socket.addEventListener('open', () => { clearTimeout(timer); resolve(); }, { once: true });
213
+ socket.addEventListener('error', () => { clearTimeout(timer); reject(new Error('visitor websocket failed')); }, { once: true });
214
+ });
215
+ const deadline = Date.now() + 3_000;
216
+ let upgrades = frames.filter((frame) => frame.type === 'ws-upgrade');
217
+ while (upgrades.length <= before) {
218
+ if (Date.now() > deadline) throw new Error('the relay never sent ws-upgrade for the visitor socket');
219
+ await new Promise((resolve) => setTimeout(resolve, 5));
220
+ upgrades = frames.filter((frame) => frame.type === 'ws-upgrade');
221
+ }
222
+ return { socket, upgrade: upgrades[upgrades.length - 1]! };
223
+ },
224
+ stop() {
225
+ for (const local of locals.values()) local.close();
226
+ control.socket.close();
227
+ relay.stop();
228
+ app.stop(true);
229
+ },
230
+ };
231
+ }
232
+
233
+ /**
234
+ * READ THE 101 ITSELF — the raw bytes of a WebSocket handshake response.
235
+ *
236
+ * §9 caught the subprotocol assertion being a fixture artifact: Bun's WebSocket CLIENT does not
237
+ * enforce RFC 6455 §4.1 for a single-element offer, so `socket.protocol` reports what the client
238
+ * REQUESTED and stays green whether or not the relay echoed anything. Response headers are
239
+ * likewise invisible to that client, so `Set-Cookie` on an upgrade cannot be seen through it at
240
+ * all. A raw TCP handshake reads what the relay actually WROTE, which is the only thing either
241
+ * claim is about.
242
+ */
243
+ async function readUpgradeHandshake(url: string, headers: Record<string, string> = {}): Promise<{ status: number; headers: Record<string, string> }> {
244
+ const target = new URL(url.replace(/^ws/, 'http'));
245
+ const lines = [
246
+ `GET ${target.pathname}${target.search} HTTP/1.1`,
247
+ `Host: ${target.host}`,
248
+ 'Upgrade: websocket',
249
+ 'Connection: Upgrade',
250
+ // A fixed key: `Sec-WebSocket-Accept` is not what is under test, and a fixed one keeps the
251
+ // handshake a pure function of the request.
252
+ 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==',
253
+ 'Sec-WebSocket-Version: 13',
254
+ ...Object.entries(headers).map(([key, value]) => `${key}: ${value}`),
255
+ ];
256
+ return new Promise((resolve, reject) => {
257
+ let buffer = '';
258
+ let settled = false;
259
+ const timer = setTimeout(() => { if (!settled) { settled = true; reject(new Error('handshake timed out')); } }, 3_000);
260
+ const finish = (fn: () => void) => { if (settled) return; settled = true; clearTimeout(timer); fn(); };
261
+ void Bun.connect({
262
+ hostname: target.hostname,
263
+ port: Number(target.port),
264
+ socket: {
265
+ open(socket) { socket.write(`${lines.join('\r\n')}\r\n\r\n`); },
266
+ data(socket, chunk) {
267
+ buffer += Buffer.from(chunk).toString('latin1');
268
+ const end = buffer.indexOf('\r\n\r\n');
269
+ if (end === -1) return;
270
+ finish(() => {
271
+ const [statusLine, ...rest] = buffer.slice(0, end).split('\r\n');
272
+ const parsed: Record<string, string> = {};
273
+ for (const line of rest) {
274
+ const colon = line.indexOf(':');
275
+ if (colon > 0) parsed[line.slice(0, colon).trim().toLowerCase()] = line.slice(colon + 1).trim();
276
+ }
277
+ socket.end();
278
+ resolve({ status: Number(statusLine?.split(' ')[1] ?? 0), headers: parsed });
279
+ });
280
+ },
281
+ error(_socket, error) { finish(() => reject(error)); },
282
+ close() { finish(() => reject(new Error('handshake socket closed before a response head'))); },
283
+ },
284
+ }).catch((error: unknown) => finish(() => reject(error as Error)));
285
+ });
286
+ }
287
+
288
+ /** The next frame a visitor socket receives, or `undefined` if it closes first. */
289
+ function nextVisitorFrame(socket: WebSocket, timeoutMs = 3_000): Promise<{ data: string | ArrayBuffer } | { closed: { code: number; reason: string } }> {
290
+ return new Promise((resolve, reject) => {
291
+ const timer = setTimeout(() => { cleanup(); reject(new Error('timed out waiting for a visitor frame')); }, timeoutMs);
292
+ const onMessage = (event: MessageEvent) => { cleanup(); resolve({ data: event.data as string | ArrayBuffer }); };
293
+ const onClose = (event: CloseEvent) => { cleanup(); resolve({ closed: { code: event.code, reason: event.reason } }); };
294
+ const cleanup = () => { clearTimeout(timer); socket.removeEventListener('message', onMessage); socket.removeEventListener('close', onClose); };
295
+ socket.addEventListener('message', onMessage);
296
+ socket.addEventListener('close', onClose);
297
+ });
298
+ }
299
+
300
+ async function protocolRoundtrip(root: string, options: { basicAuth?: { user: string; pass: string }; sendBasicAuth?: boolean; request?: RequestInit; path?: string } = {}) {
301
+ const app = Bun.serve({ hostname: '127.0.0.1', port: 0, async fetch(req) {
302
+ const body = await req.text();
303
+ return new Response(JSON.stringify({ method: req.method, path: new URL(req.url).pathname + new URL(req.url).search, body, marker: 'genuine-origin' }), {
304
+ status: 201, headers: { 'content-type': 'application/json', 'x-origin': 'loopback' },
305
+ });
306
+ } });
307
+ const relay = createTunnelTwinServer({ root });
308
+ const socket = new WebSocket(relay.url.replace(/^http/, 'ws') + '/ws');
309
+ try {
310
+ const handle = await new Promise<{ tunnelId: string; url: string }>((resolve, reject) => {
311
+ const timer = setTimeout(() => reject(new Error('relay registration timed out')), 5_000);
312
+ socket.addEventListener('open', () => socket.send(JSON.stringify({
313
+ type: 'register', tunnelId: 'protocol-proof', secret: 'vt_fake_local', authRequired: false,
314
+ ...(options.basicAuth ? { basicAuth: options.basicAuth } : {}),
315
+ })));
316
+ socket.addEventListener('message', (event) => {
317
+ const message = JSON.parse(String(event.data)) as Record<string, unknown>;
318
+ if (message.type === 'registered') { clearTimeout(timer); resolve({ tunnelId: String(message.tunnelId), url: String(message.url) }); }
319
+ if (message.type === 'error') { clearTimeout(timer); reject(new Error(String(message.message))); }
320
+ });
321
+ socket.addEventListener('error', () => { clearTimeout(timer); reject(new Error('relay socket failed')); });
322
+ });
323
+ socket.addEventListener('message', async (event) => {
324
+ const message = JSON.parse(String(event.data)) as Record<string, any>;
325
+ if (message.type !== 'request') return;
326
+ const originResponse = await fetch(`http://127.0.0.1:${app.port}${message.path}`, {
327
+ method: message.method,
328
+ headers: message.headers,
329
+ ...(message.body ? { body: Buffer.from(message.body, 'base64') } : {}),
330
+ });
331
+ const responseHeaders: Record<string, string> = {};
332
+ originResponse.headers.forEach((value, key) => { responseHeaders[key] = value; });
333
+ socket.send(JSON.stringify({
334
+ type: 'response', reqId: message.reqId, status: originResponse.status,
335
+ headers: responseHeaders, body: Buffer.from(await originResponse.arrayBuffer()).toString('base64'),
336
+ }));
337
+ });
338
+ const headers = new Headers(options.request?.headers);
339
+ if (options.basicAuth && options.sendBasicAuth !== false) headers.set('authorization', `Basic ${Buffer.from(`${options.basicAuth.user}:${options.basicAuth.pass}`).toString('base64')}`);
340
+ const response = await fetch(`${handle.url}${options.path ?? '/hello?x=1'}`, { ...options.request, headers });
341
+ const responseBody = await response.text();
342
+ let body: Record<string, unknown> = {};
343
+ try { body = JSON.parse(responseBody) as Record<string, unknown>; } catch { body = { text: responseBody }; }
344
+ return { response, body, handle };
345
+ } finally {
346
+ socket.close(); relay.stop(); app.stop(true);
347
+ }
348
+ }
349
+
350
+ async function jwtCookieProof(root: string): Promise<boolean> {
351
+ const relay = createTunnelTwinServer({ root });
352
+ const control = await openControl(relay.url, 'cookie-proof');
353
+ try {
354
+ const token = relay.mintToken('cookie-proof');
355
+ const wrongBootstrap = await fetch(relay.authUrl('cookie-proof', relay.mintToken('different-tunnel')));
356
+ if (wrongBootstrap.status !== 401 || wrongBootstrap.headers.get('set-cookie') !== null) return false;
357
+ const bootstrap = await fetch(relay.authUrl('cookie-proof', token));
358
+ const cookie = bootstrap.headers.get('set-cookie')?.split(';')[0];
359
+ if (bootstrap.status !== 200 || !cookie) return false;
360
+ const requestFrame = nextSocketMessage(control.socket, 'request');
361
+ const responsePromise = fetch(`${control.url}/cookie`, { headers: { cookie } });
362
+ const request = await requestFrame;
363
+ control.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('cookie-ok') }));
364
+ const response = await responsePromise;
365
+ const wrongToken = relay.mintToken('different-tunnel');
366
+ const wrong = await fetch(`${control.url}/cookie`, { headers: { authorization: `Bearer ${wrongToken}` } });
367
+ return response.status === 200 && await response.text() === 'cookie-ok'
368
+ && !String(request.headers.cookie ?? '').includes('__volter_auth') && wrong.status === 401;
369
+ } finally { control.socket.close(); relay.stop(); }
370
+ }
371
+
372
+ export const TUNNEL_CAPABILITIES: CapabilitySpec[] = [
373
+ // Cloudflare Quick Tunnels — control plane from the official cloudflared source + docs.
374
+ done('tunnel.cloudflare.quick.create', 'cloudflare_quick', 'POST /tunnel allocates a successful quick tunnel', 'api', 'core', () => withRoot(async (root) => {
375
+ const r = await quick(root); const b = r.body as any;
376
+ return r.status === 200 && b.success === true && b.errors.length === 0 && UUID_PATTERN.test(b.result.id);
377
+ })),
378
+ done('tunnel.cloudflare.quick.response_shape', 'cloudflare_quick', 'Allocation returns id/name/hostname/account_tag/secret in cloudflared\'s first-party response shape', 'api', 'core', () => withRoot(async (root) => {
379
+ const b = (await quick(root)).body as any;
380
+ return JSON.stringify(Object.keys(b).sort()) === JSON.stringify(['errors', 'result', 'success'])
381
+ && JSON.stringify(Object.keys(b.result).sort()) === JSON.stringify(['account_tag', 'hostname', 'id', 'name', 'secret'])
382
+ && UUID_PATTERN.test(b.result.id)
383
+ && typeof b.result.name === 'string' && b.result.name.length > 0
384
+ && typeof b.result.hostname === 'string' && /^[^.]+\.trycloudflare\.com$/.test(b.result.hostname)
385
+ && typeof b.result.account_tag === 'string' && b.result.account_tag.length > 0
386
+ && typeof b.result.secret === 'string' && b.result.secret.length > 0
387
+ && Buffer.from(b.result.secret, 'base64').toString('base64') === b.result.secret;
388
+ })),
389
+ done('tunnel.cloudflare.quick.no_account', 'cloudflare_quick', 'Quick allocation requires no Cloudflare account token', 'api', 'core', () => withRoot(async (root) => {
390
+ const r = await handleTunnelTwinRequest({ method: 'POST', path: '/tunnel', headers: {}, root, occurredAt: AT });
391
+ return r.status === 200 && (r.body as any).success === true;
392
+ })),
393
+ done('tunnel.cloudflare.quick.unique_allocations', 'cloudflare_quick', 'Two allocations receive different ids, hostnames, and secrets', 'api', 'common', () => withRoot(async (root) => {
394
+ const a = (await quick(root)).body as any; const b = (await quick(root)).body as any;
395
+ return a.result.id !== b.result.id && a.result.hostname !== b.result.hostname && a.result.secret !== b.result.secret;
396
+ })),
397
+ done('tunnel.cloudflare.quick.persisted', 'cloudflare_quick', 'Allocation is folded into the kernel as an ephemeral quick_tunnel resource', 'api', 'common', () => withRoot(async (root) => {
398
+ const r = await quick(root); const id = (r.body as any).result.id;
399
+ return projectResources('tunnel', root).some((x) => x.id === `quick:${id}` && x.type === 'quick_tunnel' && x.ephemeral === true);
400
+ })),
401
+ done('tunnel.cloudflare.quick.readonly_refusal', 'cloudflare_quick', 'Twin-only read-only mode refuses allocation without claiming a Cloudflare error code', 'api', 'niche', () => withRoot(async (root) => {
402
+ const relay = createTunnelTwinServer({ root, readOnly: true });
403
+ try {
404
+ const response = await fetch(`${relay.url}/tunnel`, { method: 'POST' });
405
+ const body = await response.json() as any;
406
+ return response.status === 405 && response.headers.get('content-type')?.startsWith('application/json') === true
407
+ && body.success === false && body.errors.length === 1
408
+ && JSON.stringify(Object.keys(body.errors[0]).sort()) === JSON.stringify(['message'])
409
+ && body.errors[0].message === 'tunnel twin is read-only' && body.errors[0].code === undefined
410
+ && listActions('tunnel', root).length === 0;
411
+ } finally { relay.stop(); }
412
+ })),
413
+ done('tunnel.cloudflare.quick.unknown_route', 'cloudflare_quick', 'An unmodeled Cloudflare route fails locally instead of fabricating success', 'api', 'common', () => withRoot(async (root) => (await quick(root, { method: 'GET', path: '/accounts' })).status === 404)),
414
+ done('tunnel.cloudflare.quick.adapter_route_boundary', 'cloudflare_quick', 'Reserved management paths still refuse after origin registration while ordinary app paths forward', 'api', 'core', () => withRoot(async (root) => {
415
+ const hits: string[] = [];
416
+ const origin = Bun.serve({ hostname: '127.0.0.1', port: 0, fetch: (request) => {
417
+ hits.push(new URL(request.url).pathname);
418
+ return new Response('app-route');
419
+ } });
420
+ const relay = createTunnelTwinServer({ root });
421
+ try {
422
+ const allocated = await fetch(`${relay.url}/tunnel`, { method: 'POST' }).then((r) => r.json()) as any;
423
+ relay.registerQuickOrigin(allocated.result.id, `http://127.0.0.1:${origin.port}`);
424
+ const reservedPaths = [
425
+ '/', '/docs', '/__volter_inspect', '/__volter_replay',
426
+ '/accounts', '/client/v4/accounts', '/me', '/admin/accounts', '/signup/github', '/report', '/waitlist',
427
+ '/api/status/unmodeled', '/%2Faccounts', '/%252Fadmin/accounts', '//signup/github',
428
+ '/%25252525252525252Faccounts',
429
+ ];
430
+ if (!tunnelControlPathIsReserved(`/${'x'.repeat(8_193)}`)
431
+ || !tunnelControlPathIsReserved('/%ZZ/accounts')
432
+ || tunnelControlPathIsReserved('/product/%252Ffloor')) return false;
433
+ const reserved = await Promise.all(reservedPaths.map(async (path) => {
434
+ const response = await fetch(`${relay.url}${path}`);
435
+ return response.status === 404 && (await response.json() as any).error === 'not found';
436
+ }));
437
+ const app = await fetch(`${relay.url}/product/floor`);
438
+ const appApi = await fetch(`${relay.url}/api/application`);
439
+ const encodedApp = await fetch(`${relay.url}/product/%252Ffloor`);
440
+ return reserved.every(Boolean) && app.status === 200 && await app.text() === 'app-route'
441
+ && appApi.status === 200 && await appApi.text() === 'app-route'
442
+ && encodedApp.status === 200 && await encodedApp.text() === 'app-route'
443
+ && JSON.stringify(hits) === JSON.stringify(['/product/floor', '/api/application', '/product/%252Ffloor']);
444
+ } finally { relay.stop(); origin.stop(true); }
445
+ })),
446
+ done('tunnel.cloudflare.quick.local_http_path', 'cloudflare_quick', 'Local quick adapter forwards bytes over a genuine loopback HTTP path', 'api', 'core', () => withRoot(async (root) => {
447
+ const origin = Bun.serve({ hostname: '127.0.0.1', port: 0, fetch: () => new Response('real-loopback-body', { headers: { 'x-origin': 'yes' } }) });
448
+ const relay = createTunnelTwinServer({ root });
449
+ try {
450
+ const allocated = await fetch(`${relay.url}/tunnel`, { method: 'POST' }).then((r) => r.json()) as any;
451
+ relay.registerQuickOrigin(allocated.result.id, `http://127.0.0.1:${origin.port}`);
452
+ const response = await fetch(`${relay.quickUrl(allocated.result.id)}/health`);
453
+ return response.headers.get('x-origin') === 'yes' && await response.text() === 'real-loopback-body';
454
+ } finally { relay.stop(); origin.stop(true); }
455
+ })),
456
+ done('tunnel.cloudflare.quick.origin_boundary', 'cloudflare_quick', 'Quick-origin registration accepts allocated credential-free IPv4/IPv6 loopback http(s) URLs and forwarded paths cannot replace that origin', 'api', 'core', () => withRoot(async (root) => {
457
+ const relay = createTunnelTwinServer({ root });
458
+ const registeredHits: Array<{ path: string; search: string }> = [];
459
+ const decoyHits: Array<{ path: string; search: string }> = [];
460
+ const registeredOrigin = Bun.serve({ hostname: '127.0.0.1', port: 0, fetch: (request) => {
461
+ const url = new URL(request.url);
462
+ registeredHits.push({ path: url.pathname, search: url.search });
463
+ return new Response('registered-origin');
464
+ } });
465
+ const decoyOrigin = Bun.serve({ hostname: '127.0.0.1', port: 0, fetch: (request) => {
466
+ const url = new URL(request.url);
467
+ decoyHits.push({ path: url.pathname, search: url.search });
468
+ return new Response('decoy-origin');
469
+ } });
470
+ try {
471
+ const allocated = await fetch(`${relay.url}/tunnel`, { method: 'POST' }).then((r) => r.json()) as any;
472
+ let remote = false; let scheme = false; let unknown = false; let credentialed = false;
473
+ let decorated = false; let backslash = false; let strictRaw = true;
474
+ try { relay.registerQuickOrigin(allocated.result.id, 'https://example.com'); } catch { remote = true; }
475
+ try { relay.registerQuickOrigin(allocated.result.id, 'file:///tmp/secret'); } catch { scheme = true; }
476
+ try { relay.registerQuickOrigin('not-allocated', 'http://127.0.0.1:3000'); } catch { unknown = true; }
477
+ try { relay.registerQuickOrigin(allocated.result.id, 'http://user:pass@127.0.0.1:3000'); } catch { credentialed = true; }
478
+ try { relay.registerQuickOrigin(allocated.result.id, 'http://127.0.0.1:3000/base?secret=1#fragment'); } catch { decorated = true; }
479
+ try { relay.registerQuickOrigin(allocated.result.id, 'http:\\\\127.0.0.1:3000'); } catch { backslash = true; }
480
+ for (const invalid of [
481
+ 'http://127.0.0.1:3000/%2e%2e',
482
+ 'http://127.1:3000',
483
+ 'http://2130706433:3000',
484
+ 'http://0x7f000001:3000',
485
+ 'http://0177.0.0.1:3000',
486
+ 'http://127.000.000.001:3000',
487
+ 'http://%31%32%37.0.0.1:3000',
488
+ 'http://127%2e0%2e0%2e1:3000',
489
+ 'http://127.0.0.1.:3000',
490
+ 'http://127.0.0.1:03000',
491
+ 'http://[::ffff:127.0.0.1]:3000',
492
+ ]) {
493
+ try { relay.registerQuickOrigin(allocated.result.id, invalid); strictRaw = false; } catch { /* expected */ }
494
+ }
495
+ relay.registerQuickOrigin(allocated.result.id, 'http://localhost:3000');
496
+ relay.registerQuickOrigin(allocated.result.id, 'https://localhost:3000');
497
+ relay.registerQuickOrigin(allocated.result.id, 'http://127.255.255.254:3000');
498
+ relay.registerQuickOrigin(allocated.result.id, 'http://[::1]:3000');
499
+ relay.registerQuickOrigin(allocated.result.id, 'http://[0:0:0:0:0:0:0:1]:3000');
500
+ relay.registerQuickOrigin(allocated.result.id, `http://127.0.0.1:${registeredOrigin.port}`);
501
+ const explicit = await fetch(`${relay.quickUrl(allocated.result.id)}//127.0.0.1:${decoyOrigin.port}/explicit?next=https%3A%2F%2Fdecoy.example`);
502
+ const explicitEncoded = await fetch(`${relay.quickUrl(allocated.result.id)}/%2F%2F127.0.0.1:${decoyOrigin.port}/encoded?q=%2F%2Fevil.example`);
503
+ const fallback = await fetch(`${relay.url}//127.0.0.1:${decoyOrigin.port}/fallback?next=https%3A%2F%2Fdecoy.example`);
504
+ const fallbackEncoded = await fetch(`${relay.url}/%2F%2F127.0.0.1:${decoyOrigin.port}/encoded?q=%2F%2Fevil.example`);
505
+ return remote && scheme && unknown && credentialed && decorated && backslash && strictRaw
506
+ && (await Promise.all([explicit, explicitEncoded, fallback, fallbackEncoded].map(async (response) => response.status === 200 && await response.text() === 'registered-origin'))).every(Boolean)
507
+ && JSON.stringify(registeredHits) === JSON.stringify([
508
+ { path: `/127.0.0.1:${decoyOrigin.port}/explicit`, search: '?next=https%3A%2F%2Fdecoy.example' },
509
+ { path: `/%2F%2F127.0.0.1:${decoyOrigin.port}/encoded`, search: '?q=%2F%2Fevil.example' },
510
+ { path: `/127.0.0.1:${decoyOrigin.port}/fallback`, search: '?next=https%3A%2F%2Fdecoy.example' },
511
+ { path: `/%2F%2F127.0.0.1:${decoyOrigin.port}/encoded`, search: '?q=%2F%2Fevil.example' },
512
+ ])
513
+ && decoyHits.length === 0;
514
+ } finally { relay.stop(); registeredOrigin.stop(true); decoyOrigin.stop(true); }
515
+ })),
516
+ done('tunnel.conformance.control_probe', 'volter_management', 'Offline conformance drives each claimed control route and relay registration through live seams', 'api', 'core', async () => {
517
+ const report = await checkTunnelConformance();
518
+ return report.ok && report.probes === 4 && report.violations.length === 0;
519
+ }),
520
+ done('tunnel.errors.json_containment', 'volter_management', 'HTTP, storage, and origin failures stay in stable JSON envelopes without runtime stack pages', 'api', 'core', () => withRoot(async (root) => {
521
+ const relay = createTunnelTwinServer({ root: '/dev/null/tunnel-impossible' });
522
+ try {
523
+ const storage = await fetch(`${relay.url}/tunnel`, { method: 'POST' });
524
+ const disconnected = await fetch(`${relay.url}/__twin/tunnels/missing/path`);
525
+ const storageBody = await storage.json() as Record<string, unknown>;
526
+ const disconnectedBody = await disconnected.json() as Record<string, unknown>;
527
+ if (storage.status !== 500 || storageBody.error !== 'Tunnel twin request failed'
528
+ || disconnected.status !== 502 || disconnectedBody.error !== 'Tunnel not connected') return false;
529
+ } finally { relay.stop(); }
530
+ const stoppedOrigin = Bun.serve({ hostname: '127.0.0.1', port: 0, fetch: () => new Response('never') });
531
+ const stoppedPort = stoppedOrigin.port;
532
+ stoppedOrigin.stop(true);
533
+ const originRelay = createTunnelTwinServer({ root });
534
+ try {
535
+ const allocated = await fetch(`${originRelay.url}/tunnel`, { method: 'POST' }).then((response) => response.json()) as any;
536
+ originRelay.registerQuickOrigin(allocated.result.id, `http://127.0.0.1:${stoppedPort}`);
537
+ const explicitUnavailable = await fetch(`${originRelay.quickUrl(allocated.result.id)}/health`);
538
+ const fallbackUnavailable = await fetch(`${originRelay.url}/health`);
539
+ return explicitUnavailable.status === 502 && (await explicitUnavailable.json() as any).error === 'Quick tunnel origin unavailable'
540
+ && fallbackUnavailable.status === 502 && (await fallbackUnavailable.json() as any).error === 'Quick tunnel origin unavailable';
541
+ } finally { originRelay.stop(); }
542
+ })),
543
+ todo('tunnel.cloudflare.quick.concurrent_200_limit', 'cloudflare_quick', 'Enforce Cloudflare Quick Tunnels\' documented 200 concurrent in-flight request cap with 429', 'api', 'common'),
544
+ todo('tunnel.cloudflare.quick.no_sse', 'cloudflare_quick', 'Reject Server-Sent Events like the documented Quick Tunnel limitation', 'api', 'niche'),
545
+ todo('tunnel.cloudflare.managed.named_tunnel', 'cloudflare_managed', 'Named tunnel creation and credentials', 'api', 'common'),
546
+ todo('tunnel.cloudflare.managed.ingress_rules', 'cloudflare_managed', 'Managed ingress configuration and hostname routing', 'api', 'common'),
547
+ todo('tunnel.cloudflare.managed.account_auth', 'cloudflare_managed', 'Account-scoped API token authentication', 'api', 'common'),
548
+ todo('tunnel.cloudflare.managed.replicas', 'cloudflare_managed', 'Multiple cloudflared replicas for one named tunnel', 'api', 'niche'),
549
+
550
+ // Owned Volter relay protocol.
551
+ done('tunnel.volter.control.register', 'volter_control', 'Relay register receives registered with the requested id and a reachable URL', 'api', 'core', () => withRoot(async (root) => {
552
+ const x = await protocolRoundtrip(root); return x.handle.tunnelId === 'protocol-proof' && x.handle.url.includes('/__twin/tunnels/protocol-proof');
553
+ })),
554
+ done('tunnel.volter.http.forward_get', 'volter_http', 'Relay frames forward GET path/query to a real local HTTP server', 'api', 'core', () => withRoot(async (root) => {
555
+ const x = await protocolRoundtrip(root); return x.response.status === 201 && x.body.path === '/hello?x=1' && x.body.marker === 'genuine-origin';
556
+ })),
557
+ done('tunnel.volter.http.forward_post_body', 'volter_http', 'POST method and body survive relay framing', 'api', 'core', () => withRoot(async (root) => {
558
+ const x = await protocolRoundtrip(root, { path: '/submit', request: { method: 'POST', body: 'payload-123' } });
559
+ return x.body.method === 'POST' && x.body.path === '/submit' && x.body.body === 'payload-123';
560
+ })),
561
+ done('tunnel.volter.http.response_status_headers', 'volter_http', 'Origin response status and headers survive relay framing', 'api', 'core', () => withRoot(async (root) => {
562
+ const x = await protocolRoundtrip(root); return x.response.status === 201 && x.response.headers.get('x-origin') === 'loopback';
563
+ })),
564
+ done('tunnel.volter.http.owned_header_rules', 'volter_http', 'Owned relay header rules strip framing headers, replace downstream CORS, and default dynamic traffic to no-store', 'api', 'common', () => withRoot(async (root) => {
565
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'headers-proof', { authRequired: false });
566
+ try {
567
+ const roundtrip = async (path: string, headers: Record<string, string>) => {
568
+ const frame = nextSocketMessage(control.socket, 'request');
569
+ const pending = fetch(`${control.url}${path}`, { headers: { origin: 'https://caller.example' } });
570
+ const req = await frame;
571
+ control.socket.send(JSON.stringify({ type: 'response', reqId: req.reqId, status: 203, headers, body: '' }));
572
+ return pending;
573
+ };
574
+ const dynamic = await roundtrip('/headers', {
575
+ 'x-frame-options': 'DENY',
576
+ 'content-security-policy': "default-src 'self'; frame-ancestors 'none'",
577
+ 'access-control-allow-origin': 'https://wrong.example',
578
+ });
579
+ if (dynamic.status !== 203 || dynamic.headers.get('x-frame-options') !== null
580
+ || String(dynamic.headers.get('content-security-policy')).includes('frame-ancestors')
581
+ || dynamic.headers.get('access-control-allow-origin') !== 'https://caller.example') return false;
582
+
583
+ const privateCases: Response[] = [];
584
+ for (const [path, headers] of [
585
+ ['/asset-conflict', { 'cache-control': 'public, private', vary: 'Accept-Encoding' }],
586
+ ['/asset-no-store', { 'cache-control': 'public, no-store' }],
587
+ ['/asset-no-cache', { 'cache-control': 'public, no-cache' }],
588
+ // The owned relay never caches API paths even when downstream says public.
589
+ ['/api/private', { 'cache-control': 'public, max-age=3600' }],
590
+ ] as Array<[string, Record<string, string>]>) privateCases.push(await roundtrip(path, headers));
591
+ for (const response of [dynamic, ...privateCases]) {
592
+ const vary = (response.headers.get('vary') ?? '').toLowerCase().split(',').map((value) => value.trim());
593
+ if (response.headers.get('cache-control') !== 'private, no-store, max-age=0'
594
+ || response.headers.get('cloudflare-cdn-cache-control') !== 'no-store'
595
+ || response.headers.get('cdn-cache-control') !== 'no-store'
596
+ || !vary.includes('cookie') || !vary.includes('authorization')) return false;
597
+ }
598
+ if (!(privateCases[0]!.headers.get('vary') ?? '').toLowerCase().includes('accept-encoding')) return false;
599
+
600
+ const publicAsset = await roundtrip('/asset-public', { 'cache-control': 'public, max-age=3600' });
601
+ return publicAsset.headers.get('cache-control') === 'public, max-age=3600'
602
+ && publicAsset.headers.get('cloudflare-cdn-cache-control') === null
603
+ && publicAsset.headers.get('cdn-cache-control') === null;
604
+ } finally { control.socket.close(); relay.stop(); }
605
+ })),
606
+ done('tunnel.volter.http.basic_auth', 'volter_auth', 'Non-empty Basic auth gates ingress while owned empty-value configs remain unconfigured', 'api', 'common', () => withRoot(async (root) => {
607
+ const basicAuth = { user: 'human', pass: 'remember-me' };
608
+ const denied = await protocolRoundtrip(root, { basicAuth, sendBasicAuth: false });
609
+ const allowed = await protocolRoundtrip(root, { basicAuth });
610
+ if (denied.response.status !== 401 || denied.response.headers.get('www-authenticate')?.includes('Basic') !== true
611
+ || allowed.response.status !== 201 || allowed.body.marker !== 'genuine-origin') return false;
612
+ for (const empty of [{ user: 'human', pass: '' }, { user: '', pass: 'secret' }, { user: '', pass: '' }]) {
613
+ const prepared = prepareTunnelRelayRegistration({
614
+ message: { type: 'register', tunnelId: 'empty-basic', secret: 'x', authRequired: false, basicAuth: empty },
615
+ session: {}, publicBaseUrl: 'http://127.0.0.1:1',
616
+ });
617
+ if (!('persistence' in prepared) || prepared.session.basicAuth !== undefined
618
+ || prepared.persistence.fields.basic_auth_configured !== false
619
+ || prepared.persistence.fields.basic_auth_sha256 !== null) return false;
620
+ const ungated = await protocolRoundtrip(root, { basicAuth: empty, sendBasicAuth: false, path: '/empty-basic' });
621
+ if (ungated.response.status !== 201 || ungated.body.marker !== 'genuine-origin') return false;
622
+ }
623
+ return true;
624
+ })),
625
+ done('tunnel.volter.control.missing_secret', 'volter_auth', 'Missing credentials and malformed Basic-auth registration frames are rejected fatally without changing session state', 'api', 'core', async () => {
626
+ const session = (): RelaySession => ({
627
+ tunnelId: 'healthy-owner', authRequired: true,
628
+ basicAuth: { user: 'sentinel', pass: 'untouched' }, registered: true,
629
+ });
630
+ const original = session();
631
+ const originalJson = JSON.stringify(original);
632
+ const missing = await handleTunnelRelayMessage({ message: { type: 'register', tunnelId: 'x', authRequired: false }, session: original, publicBaseUrl: 'http://127.0.0.1:1' });
633
+ if (missing.outbound?.type !== 'error' || missing.outbound.fatal !== true || !String(missing.outbound.message).includes('credential')
634
+ || missing.session !== original || JSON.stringify(original) !== originalJson) return false;
635
+ for (const basicAuth of [null, 'user:pass', {}, { user: 'only' }, { pass: 'only' }, { user: 7, pass: 'x' }]) {
636
+ const existing = session();
637
+ const before = JSON.stringify(existing);
638
+ const invalid = await handleTunnelRelayMessage({ message: { type: 'register', tunnelId: 'x', secret: 'credential', basicAuth }, session: existing, publicBaseUrl: 'http://127.0.0.1:1' });
639
+ if (invalid.outbound?.type !== 'error' || invalid.outbound.fatal !== true || !String(invalid.outbound.message).includes('basic-auth')
640
+ || invalid.session !== existing || JSON.stringify(existing) !== before) return false;
641
+ }
642
+ return true;
643
+ }),
644
+ done('tunnel.volter.control.readonly_refusal', 'volter_control', 'Read-only mode refuses relay registration without persisting or creating a live owner', 'api', 'core', () => withRoot(async (root) => {
645
+ const relay = createTunnelTwinServer({ root, readOnly: true });
646
+ const socket = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
647
+ try {
648
+ await new Promise<void>((resolve, reject) => {
649
+ socket.addEventListener('open', () => resolve(), { once: true });
650
+ socket.addEventListener('error', () => reject(new Error('read-only socket failed')), { once: true });
651
+ });
652
+ const outcome = nextSocketOutcome(socket, ['registered', 'error']);
653
+ socket.send(JSON.stringify({ type: 'register', tunnelId: 'read-only', secret: 'x', authRequired: false }));
654
+ const result = await outcome;
655
+ const status = await fetch(`${relay.url}/api/status`).then((response) => response.json()) as any;
656
+ return result.type === 'error' && result.fatal === true && String(result.message).includes('read-only')
657
+ && status.tunnels === 0 && listActions('tunnel', root).length === 0
658
+ && !projectResources('tunnel', root).some((resource) => resource.id === 'relay:read-only');
659
+ } finally { socket.close(); relay.stop(); }
660
+ })),
661
+ done('tunnel.volter.control.invalid_id', 'volter_control', 'Invalid tunnel ids are rejected instead of routed ambiguously', 'api', 'common', async () => {
662
+ const r = await handleTunnelRelayMessage({ message: { type: 'register', tunnelId: '../bad', secret: 'x', authRequired: false }, session: {}, publicBaseUrl: 'http://127.0.0.1:1' });
663
+ return r.outbound?.type === 'error' && r.outbound.fatal === true && String(r.outbound.message).includes('Invalid');
664
+ }),
665
+ done('tunnel.volter.control.persisted_registration', 'volter_control', 'Registration folds a relay_tunnel resource into the kernel', 'api', 'common', () => withRoot(async (root) => {
666
+ await handleTunnelRelayMessage({ message: { type: 'register', tunnelId: 'persisted', secret: 'x', authRequired: false }, session: {}, publicBaseUrl: 'http://127.0.0.1:1', root, occurredAt: AT });
667
+ return projectResources('tunnel', root).some((x) => x.id === 'relay:persisted' && x.type === 'relay_tunnel' && x.connected === true);
668
+ })),
669
+ done('tunnel.volter.control.basic_auth_log_secrecy', 'volter_auth', 'Basic-auth plaintext stays session-only; the append-only log stores only a hash and configured bit', 'api', 'core', () => withRoot(async (root) => {
670
+ await handleTunnelRelayMessage({
671
+ message: { type: 'register', tunnelId: 'secret-log', secret: 'x', basicAuth: { user: 'operator', pass: 'never-persist-this' } },
672
+ session: {}, publicBaseUrl: 'http://127.0.0.1:1', root, occurredAt: AT,
673
+ });
674
+ const serialized = JSON.stringify(listActions('tunnel', root));
675
+ const resource = projectResources('tunnel', root).find((x) => x.id === 'relay:secret-log');
676
+ const basicAuthKeys = Object.keys(resource ?? {}).filter((key) => key.startsWith('basic_auth_')).sort();
677
+ const expectedHash = createHash('sha256').update('operator:never-persist-this').digest('hex');
678
+ return !serialized.includes('never-persist-this') && !serialized.includes('operator')
679
+ && JSON.stringify(basicAuthKeys) === JSON.stringify(['basic_auth_configured', 'basic_auth_sha256'])
680
+ && resource?.basic_auth_configured === true && resource.basic_auth_sha256 === expectedHash;
681
+ })),
682
+ done('tunnel.volter.status.health', 'volter_management', 'GET /api/status reports the twin-local live socket count independently from persisted historical connection state', 'api', 'core', () => withRoot(async (root) => {
683
+ await handleTunnelRelayMessage({ message: { type: 'register', tunnelId: 'historical-only', secret: 'x', authRequired: false }, session: {}, publicBaseUrl: 'http://127.0.0.1:1', root, occurredAt: AT });
684
+ const persisted = projectResources('tunnel', root).find((resource) => resource.id === 'relay:historical-only');
685
+ const relay = createTunnelTwinServer({ root });
686
+ try {
687
+ const r = await fetch(`${relay.url}/api/status`);
688
+ const body = await r.json() as any;
689
+ return persisted?.connected === true && r.status === 200 && body.ok === true && body.relay === 'twin-local' && body.tunnels === 0;
690
+ } finally { relay.stop(); }
691
+ })),
692
+ done('tunnel.volter.control.response_ownership', 'volter_control', 'Unguessable request correlations are socket-owned and an unregistered socket cannot spoof a response', 'api', 'core', () => withRoot(async (root) => {
693
+ const relay = createTunnelTwinServer({ root });
694
+ let owner: Awaited<ReturnType<typeof openControl>> | undefined;
695
+ let rogue: WebSocket | undefined;
696
+ try {
697
+ owner = await openControl(relay.url, 'owned-response', { authRequired: false });
698
+ const rogueSocket = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
699
+ rogue = rogueSocket;
700
+ await new Promise<void>((resolve) => rogueSocket.addEventListener('open', () => resolve(), { once: true }));
701
+ const requestFrame = nextSocketMessage(owner.socket, 'request');
702
+ const responsePromise = fetch(`${owner.url}/ownership`);
703
+ const request = await requestFrame;
704
+ const rogueError = nextSocketMessage(rogueSocket, 'error');
705
+ rogueSocket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 299, headers: {}, body: btoa('rogue') }));
706
+ if (!(await rogueError).message.includes('not the registered')) return false;
707
+ const rogueRegistered = nextSocketMessage(rogueSocket, 'registered');
708
+ rogueSocket.send(JSON.stringify({ type: 'register', tunnelId: 'rogue-response', secret: 'vt_fake_local', authRequired: false }));
709
+ await rogueRegistered;
710
+ const correlationError = nextSocketMessage(rogueSocket, 'error');
711
+ rogueSocket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 299, headers: {}, body: btoa('rogue') }));
712
+ if (!(await correlationError).message.includes('not owned')) return false;
713
+ owner.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('owner') }));
714
+ const response = await responsePromise;
715
+ return /^[0-9a-f-]{36}$/.test(String(request.reqId)) && response.status === 200 && await response.text() === 'owner';
716
+ } finally { owner?.socket.close(); rogue?.close(); relay.stop(); }
717
+ })),
718
+ done('tunnel.volter.control.replace', 'volter_control', 'replace:true makes the prior socket inert and fails its in-flight requests before transfer', 'api', 'core', () => withRoot(async (root) => {
719
+ const relay = createTunnelTwinServer({ root });
720
+ let old: Awaited<ReturnType<typeof openControl>> | undefined;
721
+ let replacement: Awaited<ReturnType<typeof openControl>> | undefined;
722
+ try {
723
+ old = await openControl(relay.url, 'replace-proof', { authRequired: false });
724
+ const requestFrame = nextSocketMessage(old.socket, 'request');
725
+ const responsePromise = fetch(`${old.url}/slow`);
726
+ const request = await requestFrame;
727
+ replacement = await openControl(relay.url, 'replace-proof', { replace: true, authRequired: false });
728
+ const response = await responsePromise;
729
+ const body = await response.json() as Record<string, unknown>;
730
+ old.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('late') }));
731
+ const successorFrame = nextSocketMessage(replacement.socket, 'request');
732
+ const successorPromise = fetch(`${replacement.url}/successor`);
733
+ const successorRequest = await successorFrame;
734
+ try { old.socket.send(JSON.stringify({ type: 'response', reqId: successorRequest.reqId, status: 299, headers: {}, body: btoa('superseded') })); } catch { /* closed as required */ }
735
+ replacement.socket.send(JSON.stringify({ type: 'response', reqId: successorRequest.reqId, status: 200, headers: {}, body: btoa('successor') }));
736
+ const successor = await successorPromise;
737
+ return response.status === 502 && body.error === 'Tunnel replaced'
738
+ && successor.status === 200 && await successor.text() === 'successor'
739
+ && (await fetch(`${relay.url}/api/status`).then((r) => r.json()) as any).tunnels === 1;
740
+ } finally { old?.socket.close(); replacement?.socket.close(); relay.stop(); }
741
+ })),
742
+ done('tunnel.volter.control.replace_auth_before_transfer', 'volter_control', 'An invalid replace:true candidate cannot evict or disarm the valid owner', 'api', 'core', () => withRoot(async (root) => {
743
+ const relay = createTunnelTwinServer({ root }); const owner = await openControl(relay.url, 'auth-before-replace', { authRequired: false });
744
+ const attacker = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
745
+ const malformed = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
746
+ try {
747
+ await Promise.all([attacker, malformed].map((socket) => new Promise<void>((resolve, reject) => {
748
+ socket.addEventListener('open', () => resolve(), { once: true });
749
+ socket.addEventListener('error', () => reject(new Error('replacement candidate failed')), { once: true });
750
+ })));
751
+ const actionsBefore = listActions('tunnel', root).length;
752
+ const rejected = nextSocketMessage(attacker, 'error');
753
+ attacker.send(JSON.stringify({ type: 'register', tunnelId: 'auth-before-replace', replace: true }));
754
+ if (!(await rejected).fatal) return false;
755
+ const malformedRejected = nextSocketMessage(malformed, 'error');
756
+ malformed.send(JSON.stringify({
757
+ type: 'register', tunnelId: 'auth-before-replace', secret: 'x', replace: true,
758
+ basicAuth: { user: 'missing-pass' },
759
+ }));
760
+ const malformedError = await malformedRejected;
761
+ if (!malformedError.fatal || !String(malformedError.message).includes('basic-auth')
762
+ || listActions('tunnel', root).length !== actionsBefore) return false;
763
+ const frame = nextSocketMessage(owner.socket, 'request');
764
+ const responsePromise = fetch(`${owner.url}/still-owned`);
765
+ const request = await frame;
766
+ owner.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('owner-survived') }));
767
+ const response = await responsePromise;
768
+ return response.status === 200 && await response.text() === 'owner-survived'
769
+ && (await fetch(`${relay.url}/api/status`).then((r) => r.json()) as any).tunnels === 1;
770
+ } finally { attacker.close(); malformed.close(); owner.socket.close(); relay.stop(); }
771
+ })),
772
+ done('tunnel.volter.control.replace_persist_before_transfer', 'volter_control', 'A replacement persistence failure leaves the healthy owner and ingress live', 'api', 'core', () => withRoot(async (root) => {
773
+ const relay = createTunnelTwinServer({ root });
774
+ const owner = await openControl(relay.url, 'persist-before-replace', { authRequired: false });
775
+ const replacement = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
776
+ const savedRoot = `${root}-healthy`;
777
+ let displacedRoot = false;
778
+ try {
779
+ await new Promise<void>((resolve, reject) => {
780
+ replacement.addEventListener('open', () => resolve(), { once: true });
781
+ replacement.addEventListener('error', () => reject(new Error('replacement socket failed')), { once: true });
782
+ });
783
+ renameSync(root, savedRoot);
784
+ displacedRoot = true;
785
+ writeFileSync(root, 'not a state directory');
786
+ const rejected = nextSocketMessage(replacement, 'error');
787
+ replacement.send(JSON.stringify({
788
+ type: 'register', tunnelId: 'persist-before-replace', secret: 'x', replace: true, authRequired: false,
789
+ }));
790
+ if (!(await rejected).fatal) return false;
791
+ const requestFrame = nextSocketMessage(owner.socket, 'request');
792
+ const responsePromise = fetch(`${owner.url}/still-live`);
793
+ const request = await requestFrame;
794
+ owner.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('healthy-owner') }));
795
+ const response = await responsePromise;
796
+ const status = await fetch(`${relay.url}/api/status`).then((r) => r.json()) as any;
797
+ return response.status === 200 && await response.text() === 'healthy-owner' && status.tunnels === 1;
798
+ } finally {
799
+ if (displacedRoot) {
800
+ rmSync(root, { force: true });
801
+ renameSync(savedRoot, root);
802
+ }
803
+ replacement.close(); owner.socket.close(); relay.stop();
804
+ }
805
+ })),
806
+ done('tunnel.volter.control.replace_disconnect_durable_order', 'volter_control', 'A prior owner closing during replacement persistence cannot overwrite the sole successor\'s durable connected generation', 'api', 'core', () => withRoot(async (root) => {
807
+ let persistenceCalls = 0;
808
+ let enteredReplacement!: () => void;
809
+ let releaseReplacement!: () => void;
810
+ const entered = new Promise<void>((resolve) => { enteredReplacement = resolve; });
811
+ const held = new Promise<void>((resolve) => { releaseReplacement = resolve; });
812
+ const relay = createTunnelTwinServer({
813
+ root,
814
+ persistRegistration: async (candidate, options) => {
815
+ await persistTunnelRelayRegistration(candidate, options);
816
+ persistenceCalls += 1;
817
+ if (persistenceCalls === 2) {
818
+ enteredReplacement();
819
+ await held;
820
+ }
821
+ },
822
+ });
823
+ const owner = await openControl(relay.url, 'disconnect-order', { authRequired: false });
824
+ const first = projectResources('tunnel', root).find((resource) => resource.id === 'relay:disconnect-order');
825
+ const replacement = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
826
+ try {
827
+ await new Promise<void>((resolve, reject) => {
828
+ replacement.addEventListener('open', () => resolve(), { once: true });
829
+ replacement.addEventListener('error', () => reject(new Error('replacement ordering socket failed')), { once: true });
830
+ });
831
+ const registered = nextSocketOutcome(replacement, ['registered', 'error']);
832
+ replacement.send(JSON.stringify({
833
+ type: 'register', tunnelId: 'disconnect-order', secret: 'x', replace: true, authRequired: false,
834
+ }));
835
+ const persistenceEntered = await Promise.race([
836
+ entered.then(() => true),
837
+ new Promise<false>((resolve) => setTimeout(() => resolve(false), 1_000)),
838
+ ]);
839
+ if (!persistenceEntered) return false;
840
+ owner.socket.close();
841
+ for (let i = 0; i < 40; i++) {
842
+ if ((await fetch(`${relay.url}/api/status`).then((response) => response.json()) as any).tunnels === 0) break;
843
+ await new Promise((resolve) => setTimeout(resolve, 10));
844
+ }
845
+ releaseReplacement();
846
+ const outcome = await registered;
847
+ if (outcome.type !== 'registered') return false;
848
+
849
+ // Let the old close's queued generation-conditional disconnect run after the replacement
850
+ // turn. It must observe the successor registration id and become a no-op.
851
+ await new Promise((resolve) => setTimeout(resolve, 25));
852
+ const current = projectResources('tunnel', root).find((resource) => resource.id === 'relay:disconnect-order');
853
+ const status = await fetch(`${relay.url}/api/status`).then((response) => response.json()) as any;
854
+ const frame = nextSocketMessage(replacement, 'request');
855
+ const responsePromise = fetch(`${String(outcome.url)}/successor`);
856
+ const request = await frame;
857
+ replacement.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('successor-live') }));
858
+ const response = await responsePromise;
859
+ return persistenceCalls === 2 && first?.connected === true
860
+ && typeof first.registration_id === 'string'
861
+ && current?.connected === true && typeof current.registration_id === 'string'
862
+ && current.registration_id !== first.registration_id
863
+ && status.tunnels === 1 && response.status === 200 && await response.text() === 'successor-live';
864
+ } finally { releaseReplacement(); replacement.close(); owner.socket.close(); relay.stop(); }
865
+ })),
866
+ done('tunnel.volter.control.postappend_persist_failure_reverted', 'volter_control', 'A registration action appended before persistence reports failure is reverted by exact action id, preserving disconnected durable state and truthful audit history', 'api', 'core', () => withRoot(async (root) => {
867
+ await markTunnelDisconnected('postappend-failure', root, AT);
868
+ const relay = createTunnelTwinServer({
869
+ root,
870
+ persistRegistration: async (candidate, options) => {
871
+ await persistTunnelRelayRegistration(candidate, options);
872
+ throw new Error('injected failure after durable append');
873
+ },
874
+ });
875
+ const socket = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
876
+ try {
877
+ await new Promise<void>((resolve, reject) => {
878
+ socket.addEventListener('open', () => resolve(), { once: true });
879
+ socket.addEventListener('error', () => reject(new Error('post-append socket failed')), { once: true });
880
+ });
881
+ const rejected = nextSocketMessage(socket, 'error');
882
+ socket.send(JSON.stringify({ type: 'register', tunnelId: 'postappend-failure', secret: 'x', authRequired: false }));
883
+ if (!(await rejected).fatal) return false;
884
+ const actions = listActions('tunnel', root);
885
+ const registration = actions.find((action) => action.operation === 'relay.register'
886
+ && action.subject.id === 'relay:postappend-failure'
887
+ && (action.fields as Record<string, unknown> | undefined)?.registration_id);
888
+ const rollback = actions.find((action) => action.operation === 'relay.register.rollback'
889
+ && action.subject.id === 'relay:postappend-failure');
890
+ const resource = projectResources('tunnel', root).find((candidate) => candidate.id === 'relay:postappend-failure');
891
+ const status = await fetch(`${relay.url}/api/status`).then((response) => response.json()) as any;
892
+ return registration !== undefined && rollback?.op === 'revert'
893
+ && rollback.revertsActionId === registration.id
894
+ && resource?.connected === false && resource.registration_id === undefined
895
+ && status.tunnels === 0;
896
+ } finally { socket.close(); relay.stop(); }
897
+ })),
898
+ // ONE rule decides ownership: is the claim's own heartbeat fresh. The relay writes that
899
+ // heartbeat (reservation, control frames, idle keepalive); nothing here reads a process table,
900
+ // so the same answer holds for a claim written by another host or another shell. The four
901
+ // fixtures below all carry THIS host's pid — a stale local claim (its owner stopped writing,
902
+ // whatever became of the pid) is reclaimed exactly like a stale foreign one, and a fresh claim
903
+ // stays exclusive whoever wrote it.
904
+ done('tunnel.volter.control.stale_claim_recovery', 'volter_control', 'Relay claims live or die by bounded heartbeat freshness alone, so stale local and expired or far-future foreign reservations are reclaimed while any fresh owner stays exclusive', 'api', 'core', () => withRoot(async (root) => {
905
+ const claimsDir = join(worldPaths('tunnel', root).dir, 'relay-claims');
906
+ mkdirSync(claimsDir, { recursive: true });
907
+ const writeClaim = (tunnelId: string, claim: Record<string, unknown>) => writeFileSync(join(claimsDir, `${tunnelId}.json`), `${JSON.stringify({
908
+ tunnelId, token: `old-${tunnelId}`, serverId: 'old-server', socketId: 'old-socket', pid: process.pid,
909
+ hostname: hostname(), state: 'reserving', claimedAt: '2000-01-01T00:00:00.000Z', heartbeatAt: new Date().toISOString(),
910
+ ...claim,
911
+ })}\n`);
912
+ // Stopped writing: this host, a live pid (ours), and no heartbeat since 2000 — reclaimable.
913
+ writeClaim('stale-local', { heartbeatAt: '2000-01-01T00:00:00.000Z' });
914
+ writeClaim('expired-foreign', { hostname: 'retired-host.invalid', heartbeatAt: '2000-01-01T00:00:00.000Z' });
915
+ writeClaim('future-foreign', { hostname: 'bad-clock-host.invalid', heartbeatAt: '2999-01-01T00:00:00.000Z' });
916
+ writeClaim('fresh-foreign', { hostname: 'other-live-host.invalid' });
917
+ writeClaim('fresh-local', {});
918
+ const relay = createTunnelTwinServer({ root });
919
+ let stale: Awaited<ReturnType<typeof openControl>> | undefined;
920
+ let expired: Awaited<ReturnType<typeof openControl>> | undefined;
921
+ let future: Awaited<ReturnType<typeof openControl>> | undefined;
922
+ const contenders: WebSocket[] = [];
923
+ /** Register `tunnelId` on a socket that expects to be REFUSED. */
924
+ const refusedRegistration = async (tunnelId: string): Promise<Record<string, any>> => {
925
+ const socket = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
926
+ contenders.push(socket);
927
+ await new Promise<void>((resolve, reject) => {
928
+ socket.addEventListener('open', () => resolve(), { once: true });
929
+ socket.addEventListener('error', () => reject(new Error(`contender for ${tunnelId} failed`)), { once: true });
930
+ });
931
+ const refused = nextSocketMessage(socket, 'error');
932
+ socket.send(JSON.stringify({ type: 'register', tunnelId, secret: 'x', authRequired: false }));
933
+ return refused;
934
+ };
935
+ try {
936
+ stale = await openControl(relay.url, 'stale-local', { authRequired: false });
937
+ expired = await openControl(relay.url, 'expired-foreign', { authRequired: false });
938
+ future = await openControl(relay.url, 'future-foreign', { authRequired: false });
939
+ const foreignRefusal = await refusedRegistration('fresh-foreign');
940
+ const localRefusal = await refusedRegistration('fresh-local');
941
+ const registrations = listActions('tunnel', root).filter((action) => action.operation === 'relay.register');
942
+ return foreignRefusal.type === 'error' && localRefusal.type === 'error'
943
+ && registrations.some((action) => action.subject.id === 'relay:stale-local')
944
+ && registrations.some((action) => action.subject.id === 'relay:expired-foreign')
945
+ && registrations.some((action) => action.subject.id === 'relay:future-foreign')
946
+ && !registrations.some((action) => action.subject.id === 'relay:fresh-foreign')
947
+ && !registrations.some((action) => action.subject.id === 'relay:fresh-local');
948
+ } finally { for (const socket of contenders) socket.close(); stale?.socket.close(); expired?.socket.close(); future?.socket.close(); relay.stop(); }
949
+ })),
950
+ // The other half of the rule above: WHO writes the heartbeat. The relay does, out of its own
951
+ // traffic — so liveness is a fact this twin holds in state rather than something the serve path
952
+ // asks the host operating system.
953
+ done('tunnel.volter.control.heartbeat_written_by_traffic', 'volter_control', 'A relay\'s own control frame stamps its ownership claim with the world instant, so liveness is state the relay writes rather than a process-table probe', 'api', 'core', () => withRoot(async (root) => {
954
+ const claimPath = join(worldPaths('tunnel', root).dir, 'relay-claims', 'beating.json');
955
+ const heartbeatAt = (): number => Date.parse(String((JSON.parse(readFileSync(claimPath, 'utf8')) as Record<string, unknown>).heartbeatAt));
956
+ const relay = createTunnelTwinServer({ root });
957
+ let control: Awaited<ReturnType<typeof openControl>> | undefined;
958
+ try {
959
+ control = await openControl(relay.url, 'beating', { authRequired: false });
960
+ const atRegistration = heartbeatAt();
961
+ if (!Number.isFinite(atRegistration)) return false;
962
+ // Past the millisecond the registration stamped, so a later stamp is strictly greater.
963
+ await new Promise((resolve) => setTimeout(resolve, 25));
964
+ control.socket.send(JSON.stringify({ type: 'ws-message', data: 'a frame from a live relay' }));
965
+ for (let attempt = 0; attempt < 50; attempt++) {
966
+ if (heartbeatAt() > atRegistration) return true;
967
+ await new Promise((resolve) => setTimeout(resolve, 20));
968
+ }
969
+ return false;
970
+ } finally { control?.socket.close(); relay.stop(); }
971
+ })),
972
+ done('tunnel.volter.control.concurrent_claim_single_owner', 'volter_control', 'Concurrent claims without replace permission leave exactly one registered traffic owner', 'api', 'core', () => withRoot(async (root) => {
973
+ let persisted = 0;
974
+ let enteredPersistence: (() => void) | undefined;
975
+ let releasePersistence: (() => void) | undefined;
976
+ const entered = new Promise<void>((resolve) => { enteredPersistence = resolve; });
977
+ const overlap = new Promise<void>((resolve) => { releasePersistence = resolve; });
978
+ const relay = createTunnelTwinServer({
979
+ root,
980
+ persistRegistration: async (candidate, options) => {
981
+ await persistTunnelRelayRegistration(candidate, options);
982
+ persisted += 1;
983
+ enteredPersistence?.();
984
+ await overlap;
985
+ },
986
+ });
987
+ const first = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
988
+ const second = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
989
+ try {
990
+ await Promise.all([first, second].map((socket) => new Promise<void>((resolve, reject) => {
991
+ socket.addEventListener('open', () => resolve(), { once: true });
992
+ socket.addEventListener('error', () => reject(new Error('claim socket failed')), { once: true });
993
+ })));
994
+ // Attach rejection handlers immediately: the mutation harness deliberately replaces the
995
+ // registration seam with a no-op response, so neither socket is guaranteed to reach the
996
+ // persistence rendezvous below. A pending outcome must become a named red verify, not an
997
+ // unhandled timer rejection that aborts the entire mutation run.
998
+ const firstOutcome = nextSocketOutcome(first, ['registered', 'error'])
999
+ .catch((error): Record<string, any> => ({ type: 'timeout', message: String(error) }));
1000
+ const secondOutcome = nextSocketOutcome(second, ['registered', 'error'])
1001
+ .catch((error): Record<string, any> => ({ type: 'timeout', message: String(error) }));
1002
+ const claim = JSON.stringify({ type: 'register', tunnelId: 'single-owner', secret: 'x', authRequired: false });
1003
+ first.send(claim);
1004
+ const enteredBeforeTimeout = await Promise.race([
1005
+ entered.then(() => true),
1006
+ new Promise<false>((resolve) => setTimeout(() => resolve(false), 3_100)),
1007
+ ]);
1008
+ if (!enteredBeforeTimeout) return false;
1009
+ second.send(claim);
1010
+ // The second frame is now pending at the same id while the first persistence seam is held.
1011
+ // It must not enter persistence or append an action; only releasing the first winner lets the
1012
+ // serialized ownership decision reject it.
1013
+ await new Promise((resolve) => setTimeout(resolve, 50));
1014
+ if (persisted !== 1 || listActions('tunnel', root).filter((action) => action.operation === 'relay.register').length !== 1) return false;
1015
+ releasePersistence?.();
1016
+ const outcomes = await Promise.all([firstOutcome, secondOutcome]);
1017
+ const winnerIndex = outcomes.findIndex((outcome) => outcome.type === 'registered');
1018
+ if (winnerIndex < 0 || outcomes.filter((outcome) => outcome.type === 'registered').length !== 1
1019
+ || outcomes.filter((outcome) => outcome.type === 'error').length !== 1) return false;
1020
+ const winner = winnerIndex === 0 ? first : second;
1021
+ const url = String(outcomes[winnerIndex]!.url);
1022
+ const requestFrame = nextSocketMessage(winner, 'request');
1023
+ const responsePromise = fetch(`${url}/winner`);
1024
+ const request = await requestFrame;
1025
+ winner.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('one-owner') }));
1026
+ const response = await responsePromise;
1027
+ const status = await fetch(`${relay.url}/api/status`).then((r) => r.json()) as any;
1028
+ if (persisted !== 1 || response.status !== 200 || await response.text() !== 'one-owner' || status.tunnels !== 1) return false;
1029
+
1030
+ // A second OS process with a separate server/controls map but the SAME root must observe the
1031
+ // transient live-ownership claim and reject before append too. This is the branch an
1032
+ // in-process Map-only mutex cannot cover.
1033
+ const moduleUrl = new URL('./tunnel-server.ts', import.meta.url).href;
1034
+ const childScript = `
1035
+ const { createTunnelTwinServer } = await import(${JSON.stringify(moduleUrl)});
1036
+ const relay = createTunnelTwinServer({ root: ${JSON.stringify(root)} });
1037
+ const socket = new WebSocket(relay.url.replace(/^http/, 'ws') + '/ws');
1038
+ const outcome = await new Promise((resolve, reject) => {
1039
+ const timer = setTimeout(() => reject(new Error('cross-process claim timeout')), 3000);
1040
+ socket.addEventListener('open', () => socket.send(JSON.stringify({ type: 'register', tunnelId: 'single-owner', secret: 'x', authRequired: false })));
1041
+ socket.addEventListener('message', (event) => {
1042
+ const message = JSON.parse(String(event.data));
1043
+ if (message.type === 'registered' || message.type === 'error') { clearTimeout(timer); resolve(message); }
1044
+ });
1045
+ socket.addEventListener('error', () => reject(new Error('cross-process claim socket failed')));
1046
+ });
1047
+ console.log(JSON.stringify(outcome));
1048
+ socket.close(); relay.stop();
1049
+ `;
1050
+ const child = Bun.spawn([process.execPath, '-e', childScript], { stdout: 'pipe', stderr: 'pipe' });
1051
+ const [childStdout, childStderr, childExit] = await Promise.all([
1052
+ new Response(child.stdout).text(), new Response(child.stderr).text(), child.exited,
1053
+ ]);
1054
+ const crossProcess = JSON.parse(childStdout.trim()) as Record<string, unknown>;
1055
+ return childExit === 0 && childStderr === '' && crossProcess.type === 'error'
1056
+ && listActions('tunnel', root).filter((action) => action.operation === 'relay.register').length === 1;
1057
+ } finally { releasePersistence?.(); first.close(); second.close(); relay.stop(); }
1058
+ })),
1059
+ done('tunnel.volter.control.socket_single_identity', 'volter_control', 'One socket can own only one current ID; valid alias movement retires and disconnects the old mapping', 'api', 'core', () => withRoot(async (root) => {
1060
+ const relay = createTunnelTwinServer({ root }); const socket = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
1061
+ try {
1062
+ await new Promise<void>((resolve) => socket.addEventListener('open', () => resolve(), { once: true }));
1063
+ let registered = nextSocketMessage(socket, 'registered');
1064
+ socket.send(JSON.stringify({ type: 'register', tunnelId: 'alias-a', secret: 'x', authRequired: false }));
1065
+ const first = await registered;
1066
+ registered = nextSocketMessage(socket, 'registered');
1067
+ socket.send(JSON.stringify({ type: 'register', tunnelId: 'alias-b', secret: 'x', authRequired: false }));
1068
+ const second = await registered;
1069
+ const old = await fetch(String(first.url));
1070
+ const frame = nextSocketMessage(socket, 'request');
1071
+ const responsePromise = fetch(`${String(second.url)}/active`);
1072
+ const request = await frame;
1073
+ socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('alias-b') }));
1074
+ const current = await responsePromise;
1075
+ const oldResource = projectResources('tunnel', root).find((x) => x.id === 'relay:alias-a');
1076
+ return old.status === 502 && current.status === 200 && await current.text() === 'alias-b'
1077
+ && oldResource?.connected === false
1078
+ && (await fetch(`${relay.url}/api/status`).then((r) => r.json()) as any).tunnels === 1;
1079
+ } finally { socket.close(); relay.stop(); }
1080
+ })),
1081
+ done('tunnel.volter.status.live_disconnect', 'volter_management', 'Live status and persisted connected state fall to zero/false after the owning socket closes', 'api', 'core', () => withRoot(async (root) => {
1082
+ const relay = createTunnelTwinServer({ root });
1083
+ const control = await openControl(relay.url, 'close-proof', { authRequired: false });
1084
+ try {
1085
+ if ((await fetch(`${relay.url}/api/status`).then((r) => r.json()) as any).tunnels !== 1) return false;
1086
+ const requestFrame = nextSocketMessage(control.socket, 'request');
1087
+ const pendingResponse = fetch(`${control.url}/pending-at-close`);
1088
+ await requestFrame;
1089
+ control.socket.close();
1090
+ const failed = await pendingResponse;
1091
+ if (failed.status !== 502 || (await failed.json() as any).error !== 'Tunnel disconnected') return false;
1092
+ for (let i = 0; i < 40; i++) {
1093
+ const status = await fetch(`${relay.url}/api/status`).then((r) => r.json()) as any;
1094
+ const resource = projectResources('tunnel', root).find((x) => x.id === 'relay:close-proof');
1095
+ if (status.tunnels === 0 && resource?.connected === false) return true;
1096
+ await new Promise((resolve) => setTimeout(resolve, 10));
1097
+ }
1098
+ return false;
1099
+ } finally { control.socket.close(); relay.stop(); }
1100
+ })),
1101
+ done('tunnel.volter.auth.jwt_default', 'volter_auth', 'SDK-default authRequired=true denies anonymous traffic and accepts valid owned shared-SSO or tunnel-bound HS256 tokens', 'api', 'core', () => withRoot(async (root) => {
1102
+ const relay = createTunnelTwinServer({ root });
1103
+ const control = await openControl(relay.url, 'jwt-default');
1104
+ try {
1105
+ const denied = await fetch(`${control.url}/private`);
1106
+ if (denied.status !== 401) return false;
1107
+ const sharedToken = createTunnelTwinJwt({ sub: 'shared-user', exp: Math.floor(Date.now() / 1000) + 60 });
1108
+ let requestFrame = nextSocketMessage(control.socket, 'request');
1109
+ const sharedPromise = fetch(`${control.url}/shared?keep=1&__volter_token=${encodeURIComponent(sharedToken)}`);
1110
+ let request = await requestFrame;
1111
+ control.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa(String(request.path)) }));
1112
+ const shared = await sharedPromise;
1113
+ if (shared.status !== 200 || await shared.text() !== '/shared?keep=1') return false;
1114
+ requestFrame = nextSocketMessage(control.socket, 'request');
1115
+ const allowedPromise = fetch(`${control.url}/private?keep=1&__volter_token=${encodeURIComponent(relay.mintToken('jwt-default'))}`);
1116
+ request = await requestFrame;
1117
+ control.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa(String(request.path)) }));
1118
+ const allowed = await allowedPromise;
1119
+ return allowed.status === 200 && await allowed.text() === '/private?keep=1' && allowed.headers.get('set-cookie')?.includes('__volter_auth=') === true;
1120
+ } finally { control.socket.close(); relay.stop(); }
1121
+ })),
1122
+ done('tunnel.volter.auth.jwt_claim_types', 'volter_auth', 'JWT exp/nbf and present tid claims are validated, with missing tid rejected only in explicit requireTid mode', 'api', 'core', () => withRoot(async (root) => {
1123
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'jwt-types');
1124
+ try {
1125
+ const exp = await fetch(`${control.url}/x?__volter_token=${encodeURIComponent(relay.mintToken('jwt-types', { exp: 'never' }))}`);
1126
+ const nbf = await fetch(`${control.url}/x?__volter_token=${encodeURIComponent(relay.mintToken('jwt-types', { nbf: 'later' }))}`);
1127
+ const mismatch = await fetch(`${control.url}/x?__volter_token=${encodeURIComponent(relay.mintToken('another-tunnel'))}`);
1128
+ if (exp.status !== 401 || nbf.status !== 401 || mismatch.status !== 401) return false;
1129
+
1130
+ const strictRelay = createTunnelTwinServer({ root, requireTid: true, requestTimeoutMs: 200 });
1131
+ const strict = await openControl(strictRelay.url, 'jwt-strict');
1132
+ try {
1133
+ const missingTid = createTunnelTwinJwt({ sub: 'twin-local', exp: Math.floor(Date.now() / 1000) + 60 });
1134
+ const nonStringTid = createTunnelTwinJwt({ sub: 'twin-local', tid: 7 as unknown as string, exp: Math.floor(Date.now() / 1000) + 60 });
1135
+ const missing = await fetch(`${strict.url}/x?__volter_token=${encodeURIComponent(missingTid)}`);
1136
+ const typed = await fetch(`${strict.url}/x?__volter_token=${encodeURIComponent(nonStringTid)}`);
1137
+ const requestFrame = nextSocketMessage(strict.socket, 'request');
1138
+ const exactPromise = fetch(`${strict.url}/x?__volter_token=${encodeURIComponent(strictRelay.mintToken('jwt-strict'))}`);
1139
+ const request = await requestFrame;
1140
+ strict.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('bound') }));
1141
+ const exact = await exactPromise;
1142
+ return missing.status === 401 && typed.status === 401 && exact.status === 200 && await exact.text() === 'bound';
1143
+ } finally { strict.socket.close(); strictRelay.stop(); }
1144
+ } finally { control.socket.close(); relay.stop(); }
1145
+ })),
1146
+ done('tunnel.volter.http.malformed_response_contained', 'volter_http', 'Malformed complete response status/headers/body fail the owned visitor with stable JSON 502 instead of stranding it', 'api', 'core', () => withRoot(async (root) => {
1147
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'malformed-response', { authRequired: false });
1148
+ try {
1149
+ for (const malformed of [
1150
+ { status: 999, headers: {}, body: '' },
1151
+ { status: 200, headers: { 'bad\nname': 'x' }, body: '' },
1152
+ { status: 200, headers: {}, body: '***not-base64***' },
1153
+ ]) {
1154
+ const frame = nextSocketMessage(control.socket, 'request');
1155
+ const responsePromise = fetch(`${control.url}/malformed`);
1156
+ const request = await frame;
1157
+ control.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, ...malformed }));
1158
+ const response = await responsePromise;
1159
+ if (response.status !== 502 || (await response.json() as any).error !== 'Malformed tunnel response frame') return false;
1160
+ }
1161
+ return true;
1162
+ } finally { control.socket.close(); relay.stop(); }
1163
+ })),
1164
+ done('tunnel.volter.http.malformed_stream_sequence_contained', 'volter_http', 'Malformed or mixed stream response sequences terminate with a bounded error instead of stranding the visitor', 'api', 'core', () => withRoot(async (root) => {
1165
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'malformed-stream', { authRequired: false });
1166
+ try {
1167
+ const beforeStart = [
1168
+ await relayFrameOutcome(control, '/chunk-before-start', [{ type: 'response-chunk', data: btoa('x') }]),
1169
+ await relayFrameOutcome(control, '/end-before-start', [{ type: 'response-end' }]),
1170
+ await relayFrameOutcome(control, '/bad-start', [{ type: 'response-start', status: 999, headers: {} }]),
1171
+ ];
1172
+ if (!beforeStart.every((outcome) => outcome.kind === 'response' && outcome.status === 502)) return false;
1173
+ const afterStart = [
1174
+ await relayFrameOutcome(control, '/duplicate-start', [
1175
+ { type: 'response-start', status: 200, headers: {} },
1176
+ { type: 'response-chunk', data: btoa('first') },
1177
+ { type: 'response-start', status: 201, headers: {} },
1178
+ ]),
1179
+ await relayFrameOutcome(control, '/complete-after-start', [
1180
+ { type: 'response-start', status: 200, headers: {} },
1181
+ { type: 'response-chunk', data: btoa('first') },
1182
+ { type: 'response', status: 200, headers: {}, body: btoa('wrong-shape') },
1183
+ ]),
1184
+ await relayFrameOutcome(control, '/bad-chunk-after-start', [
1185
+ { type: 'response-start', status: 200, headers: {} },
1186
+ { type: 'response-chunk', data: btoa('first') },
1187
+ { type: 'response-chunk', data: '***not-base64***' },
1188
+ ]),
1189
+ ];
1190
+ // The 502 is only reachable because the head is NOT committed at `response-start`
1191
+ // (tunnel-server.ts says why, and tunnel-stream-boundary.test.ts pins the runtime fact
1192
+ // behind it). Each sequence now carries a VALID chunk before the malformed frame, so a
1193
+ // relay that had already begun delivering would answer these with a truncated 200 —
1194
+ // which is what this half would then be asserting away.
1195
+ return afterStart.every((outcome) => outcome.kind === 'response' && outcome.status === 502);
1196
+ } finally { control.socket.close(); relay.stop(); }
1197
+ })),
1198
+ // ── THE THREE STREAMING GAPS, AND THE MEASURED REASON THEY STAY TODO ────────────────
1199
+ //
1200
+ // All three need the relay to COMMIT a response head at `response-start` and deliver chunks
1201
+ // as they land. The blocker is not effort: through `Bun.serve`'s Response surface — the HTTP
1202
+ // host this relay uses, because it is also where `server.upgrade` and therefore the whole
1203
+ // WebSocket bridge come from — a body that has begun cannot be failed. Erroring the
1204
+ // `ReadableStream` behind a Response ends the chunked body cleanly, so a visitor reads a
1205
+ // truncated payload as a successful 200 and cannot tell it from a complete one — a fake
1206
+ // success — and a `content-length` that would have made the truncation detectable is dropped
1207
+ // the moment the body is a stream.
1208
+ //
1209
+ // §9 refuted the BROADER form of that sentence, correctly: `node:http` can signal a mid-body
1210
+ // failure on this same runtime, in this same process. So this is a TRADE with a named
1211
+ // alternative (re-host the HTTP plane, lose `server.upgrade`), not an impossibility, and
1212
+ // `tunnel-stream-boundary.test.ts` measures all three facts — the two limitations AND the
1213
+ // alternative — rather than only the half that supports the decision. Until the first two
1214
+ // flip, this relay buffers to `response-end`, which is what keeps
1215
+ // `malformed_stream_sequence_contained`'s 502 reachable at all.
1216
+ //
1217
+ // `stream_backpressure` has a second, independent blocker worth stating: the owned protocol's
1218
+ // fifteen discriminators contain no pause frame, so a relay cannot ask a client to slow down.
1219
+ // The only expressible bound is `request-abort`, which STOPS the request rather than pacing it.
1220
+ todo('tunnel.volter.http.streaming', 'volter_http', 'Reliable incremental visitor delivery for response-start/chunk/end (blocked: a committed body cannot be failed on this runtime — see tunnel-stream-boundary.test.ts)', 'api', 'core'),
1221
+ todo('tunnel.volter.http.stream_backpressure', 'volter_http', 'Backpressure from a slow visitor pauses or bounds client response-chunk production (blocked twice: no committed body, and the protocol has no pause frame)', 'api', 'core'),
1222
+ todo('tunnel.volter.http.stream_cancel_abort', 'volter_http', 'Canceling a streamed visitor response reliably sends request-abort (blocked: there is no committed visitor body to cancel while the relay buffers)', 'api', 'core'),
1223
+ // A STRUCTURAL gap in the protocol, filed rather than papered over (§9). `server.upgrade`
1224
+ // answers the browser's FIRST offered subprotocol, and the 101 must go out before `ws-ready`
1225
+ // exists — so the relay commits to one before the client has dialled the local server, which
1226
+ // may pick a DIFFERENT member of the full list the `ws-upgrade` frame forwards. None of the
1227
+ // vendor's fifteen discriminators can carry that choice back: `ws-ready` carries only `connId`.
1228
+ // A single-offer browser (the overwhelmingly common case, and what `websocket.upgrade` proves
1229
+ // end to end) cannot hit it; a multi-offer one can, silently.
1230
+ todo('tunnel.volter.websocket.subprotocol_negotiation', 'volter_websocket', 'A multi-offer subprotocol is negotiated with the LOCAL server rather than committed on the 101 (blocked: no discriminator carries the local choice back — ws-ready is connId only)', 'api', 'common'),
1231
+ todo('tunnel.volter.control.reconnect_backoff', 'volter_control', 'Client reconnect and stable-link backoff reset behavior', 'api', 'common'),
1232
+ todo('tunnel.volter.control.quota_frame', 'volter_control', 'Quota level frames with daily/monthly windows', 'api', 'common'),
1233
+ done('tunnel.volter.http.visitor_disconnect_abort', 'volter_http', 'A visitor TCP disconnect before response-start reliably sends request-abort through Bun\'s server boundary', 'api', 'core', () => withRoot(async (root) => {
1234
+ // The visitor walks away while the local server is still working. Unlike the streamed-response
1235
+ // reliability gaps, this one IS observable on this runtime: `Request.signal` fires on a
1236
+ // visitor hang-up, and what the relay must do with it is stop the client.
1237
+ const relay = createTunnelTwinServer({ root, requestTimeoutMs: 30_000 });
1238
+ const control = await openControl(relay.url, 'visitor-hangup', { authRequired: false });
1239
+ try {
1240
+ const aborter = new AbortController();
1241
+ const requestFrame = nextSocketMessage(control.socket, 'request');
1242
+ const visitorFailure = fetch(`${control.url}/slow`, { signal: aborter.signal }).then(() => 'completed' as const, () => 'aborted' as const);
1243
+ const request = await requestFrame;
1244
+ // No response frame at all: the client is still reading its local server when the browser
1245
+ // hangs up. The relay's request timeout is 30s, so a `request-abort` arriving here can only
1246
+ // have come from the disconnect.
1247
+ aborter.abort();
1248
+ const abort = await nextSocketMessage(control.socket, 'request-abort');
1249
+ const visitor = await visitorFailure;
1250
+
1251
+ // …and the request is genuinely FORGOTTEN: a late response frame for it is refused rather
1252
+ // than resolving a visitor that is already gone.
1253
+ const late = nextSocketMessage(control.socket, 'error');
1254
+ control.socket.send(JSON.stringify({ type: 'response', reqId: request.reqId, status: 200, headers: {}, body: btoa('too late') }));
1255
+ const refusal = await late;
1256
+ return (
1257
+ abort.reqId === request.reqId &&
1258
+ visitor === 'aborted' &&
1259
+ String(refusal.message).includes('not owned by this control socket')
1260
+ );
1261
+ } finally { control.socket.close(); relay.stop(); }
1262
+ })),
1263
+ done('tunnel.volter.http.cors_preflight', 'volter_http', 'CORS preflight succeeds before visitor auth and is not forwarded to the origin', 'api', 'common', () => withRoot(async (root) => {
1264
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'cors-proof');
1265
+ try {
1266
+ let forwarded = 0;
1267
+ const observe = (event: MessageEvent) => {
1268
+ const message = JSON.parse(String(event.data)) as Record<string, unknown>;
1269
+ if (message.type === 'request') forwarded += 1;
1270
+ };
1271
+ control.socket.addEventListener('message', observe);
1272
+ const response = await fetch(`${control.url}/anything`, {
1273
+ method: 'OPTIONS', headers: { origin: 'https://caller.example', 'access-control-request-headers': 'x-custom' },
1274
+ });
1275
+ await new Promise((resolve) => setTimeout(resolve, 25));
1276
+ control.socket.removeEventListener('message', observe);
1277
+ return response.status === 204 && response.headers.get('access-control-allow-origin') === 'https://caller.example'
1278
+ && response.headers.get('access-control-allow-headers') === 'x-custom' && forwarded === 0;
1279
+ } finally { control.socket.close(); relay.stop(); }
1280
+ })),
1281
+ todo('tunnel.volter.http.forwarded_headers', 'volter_http', 'x-forwarded-for/host/proto are normalized like the owned relay', 'api', 'common'),
1282
+ todo('tunnel.volter.http.response_header_rules', 'volter_http', 'Operator response-header remove/set/append rules', 'api', 'niche'),
1283
+ todo('tunnel.volter.http.rate_burst', 'volter_http', 'Per-tunnel burst limiter returns 429 with Retry-After', 'api', 'common'),
1284
+ done('tunnel.volter.websocket.upgrade', 'volter_websocket', 'Browser WebSocket upgrade bridges ws-upgrade/ws-ready', 'api', 'core', () => withRoot(async (root) => {
1285
+ const bridge = await openWsBridge(root);
1286
+ try {
1287
+ // A SUBPROTOCOL is offered, because a browser that asks for one and gets a 101 without
1288
+ // `Sec-WebSocket-Protocol` back fails the connection outright — the vendor's own client
1289
+ // names Vite's `vite-hmr` as the case that breaks.
1290
+ //
1291
+ // TWO are offered, and the 101 is read as RAW BYTES. §9 caught the single-offer version of
1292
+ // this assertion being a fixture artifact: Bun's WebSocket client does not enforce RFC 6455
1293
+ // §4.1 for a one-element offer, so `socket.protocol` echoed the client's own REQUEST.
1294
+ // Reading the response head is what makes this a claim about what the relay wrote — and it
1295
+ // is the pin on a contract the RUNTIME currently satisfies (`server.upgrade` answers with
1296
+ // the first offer by itself), which is exactly why it needs one: without it, nothing would
1297
+ // notice the day that stopped being true.
1298
+ const handshake = await readUpgradeHandshake(`${bridge.control.url.replace(/^http/, 'ws')}/socket?room=1`, {
1299
+ 'Sec-WebSocket-Protocol': 'vite-hmr, graphql-ws',
1300
+ });
1301
+ const { socket: visitor, upgrade } = await bridge.visitor('/socket?room=1', ['vite-hmr', 'graphql-ws']);
1302
+ // The bridge is LIVE, not merely announced: a frame sent by the browser reaches the real
1303
+ // local server and its answer comes back. That is what an upgrade with no bridge behind it
1304
+ // could not do.
1305
+ visitor.send('ping');
1306
+ const echoed = await nextVisitorFrame(visitor);
1307
+ visitor.close();
1308
+ return (
1309
+ upgrade !== undefined &&
1310
+ UUID_PATTERN.test(String(upgrade.connId)) &&
1311
+ // the tunnelled path and query reach the client, which is what it dials locally
1312
+ upgrade.path === '/socket?room=1' &&
1313
+ typeof upgrade.headers?.['sec-websocket-key'] === 'string' &&
1314
+ // negotiated end to end: the relay's own 101 names it (read off the wire, not off the
1315
+ // client's request), the browser's socket agrees, and the frame forwarded the full offer
1316
+ // so the client can dial the local server with it
1317
+ handshake.status === 101 &&
1318
+ handshake.headers['sec-websocket-protocol'] === 'vite-hmr' &&
1319
+ visitor.protocol === 'vite-hmr' &&
1320
+ upgrade.headers['sec-websocket-protocol'] === 'vite-hmr, graphql-ws' &&
1321
+ 'data' in echoed &&
1322
+ echoed.data === 'echo:/socket?room=1:ping'
1323
+ );
1324
+ } finally { bridge.stop(); }
1325
+ })),
1326
+ done('tunnel.volter.websocket.messages', 'volter_websocket', 'Text and binary WebSocket frames bridge bidirectionally', 'api', 'core', () => withRoot(async (root) => {
1327
+ const bridge = await openWsBridge(root);
1328
+ try {
1329
+ const { socket: visitor } = await bridge.visitor('/echo');
1330
+ visitor.send('hello');
1331
+ const text = await nextVisitorFrame(visitor);
1332
+ // The local server REVERSES binary payloads, so an accidental text round trip cannot
1333
+ // satisfy this half — and the `binary` flag has to survive both directions for the local
1334
+ // server to have received a binary frame at all.
1335
+ visitor.send(new Uint8Array([1, 2, 3, 4]));
1336
+ const binary = await nextVisitorFrame(visitor);
1337
+ visitor.close();
1338
+ const relayedBinary = bridge.frames.filter((frame) => frame.type === 'ws-message' && frame.binary === true);
1339
+ const relayedText = bridge.frames.filter((frame) => frame.type === 'ws-message' && frame.binary === false);
1340
+ return (
1341
+ 'data' in text && text.data === 'echo:/echo:hello' &&
1342
+ 'data' in binary && binary.data instanceof ArrayBuffer &&
1343
+ [...new Uint8Array(binary.data)].join(',') === '4,3,2,1' &&
1344
+ relayedText.length >= 1 && relayedBinary.length >= 1
1345
+ );
1346
+ } finally { bridge.stop(); }
1347
+ })),
1348
+ done('tunnel.volter.websocket.close', 'volter_websocket', 'Close code/reason bridges in both directions and the reason is clamped to 123 bytes', 'api', 'common', () => withRoot(async (root) => {
1349
+ const bridge = await openWsBridge(root);
1350
+ try {
1351
+ // ── browser → client: the visitor hangs up, the client is told ──
1352
+ const { socket: visitor } = await bridge.visitor('/bye');
1353
+ visitor.send('ping');
1354
+ await nextVisitorFrame(visitor);
1355
+ visitor.close(4123, 'visitor done');
1356
+ const relayed = await nextSocketMessage(bridge.control.socket, 'ws-close');
1357
+
1358
+ // ── client → browser: a ws-close frame closes the visitor, with the code and a reason
1359
+ // clamped to the 123 bytes a close frame can carry ──
1360
+ const second = await bridge.visitor('/bye2');
1361
+ const closing = nextVisitorFrame(second.socket);
1362
+ bridge.control.socket.send(JSON.stringify({ type: 'ws-close', connId: second.upgrade.connId, code: 4004, reason: 'x'.repeat(200) }));
1363
+ const closed = await closing;
1364
+ // …and an impossible code is normalised rather than sent: 1006 may never appear on the wire.
1365
+ const third = await bridge.visitor('/bye3');
1366
+ const thirdClosing = nextVisitorFrame(third.socket);
1367
+ bridge.control.socket.send(JSON.stringify({ type: 'ws-close', connId: third.upgrade.connId, code: 1006 }));
1368
+ const thirdClosed = await thirdClosing;
1369
+ return (
1370
+ // The CODE is what the relay carries outward; the reason a browser sends is not
1371
+ // delivered to the server handler on this runtime, so asserting it here would be
1372
+ // asserting something the relay never sees. The reason IS asserted in the other
1373
+ // direction, below, where the relay is the one producing it.
1374
+ relayed.code === 4123 && typeof relayed.reason === 'string' &&
1375
+ 'closed' in closed && closed.closed.code === 4004 && closed.closed.reason === 'x'.repeat(123) &&
1376
+ 'closed' in thirdClosed && thirdClosed.closed.code === 1000
1377
+ );
1378
+ } finally { bridge.stop(); }
1379
+ })),
1380
+ done('tunnel.volter.auth.jwt_cookie', 'volter_auth', 'JWT cookie authentication strips the relay cookie before forwarding and enforces tunnel-id binding', 'api', 'core', () => withRoot(jwtCookieProof)),
1381
+ done('tunnel.volter.auth.cookie_bootstrap', 'volter_auth', 'GET /__volter_auth validates a token and mints a path-scoped local relay cookie', 'api', 'common', () => withRoot(jwtCookieProof)),
1382
+ todo('tunnel.volter.auth.constant_time_secret', 'volter_auth', 'Shared secret verification is constant-time', 'api', 'common'),
1383
+ todo('tunnel.volter.reservations.claim', 'volter_reservations', 'Persistent tunnel-id reservation claim/refresh/reclaim', 'api', 'common'),
1384
+ todo('tunnel.volter.reservations.release_self', 'volter_reservations', 'DELETE /me/reservations/:tunnelId releases the caller-owned reservation', 'api', 'common'),
1385
+ todo('tunnel.volter.reservations.release_admin', 'volter_reservations', 'DELETE /admin/reservations/:tunnelId revokes a reservation as root', 'api', 'niche'),
1386
+ todo('tunnel.volter.accounts.whoami', 'volter_accounts', 'GET /me returns account and usage snapshot', 'api', 'common'),
1387
+ todo('tunnel.volter.accounts.device_tokens_list', 'volter_accounts', 'GET /me/tokens lists the caller account device credentials', 'api', 'niche'),
1388
+ todo('tunnel.volter.accounts.device_tokens_restore', 'volter_accounts', 'POST /me/tokens/:tokenId/restore restores a revoked device credential', 'api', 'niche'),
1389
+ todo('tunnel.volter.accounts.device_tokens_revoke', 'volter_accounts', 'DELETE /me/tokens/:tokenId revokes a device credential', 'api', 'niche'),
1390
+ todo('tunnel.volter.accounts.admin_list', 'volter_accounts', 'GET /admin/accounts lists accounts', 'api', 'niche'),
1391
+ todo('tunnel.volter.accounts.admin_create', 'volter_accounts', 'POST /admin/accounts creates an account', 'api', 'niche'),
1392
+ todo('tunnel.volter.accounts.admin_tokens_list', 'volter_accounts', 'GET /admin/accounts/:slug/tokens lists service tokens', 'api', 'niche'),
1393
+ todo('tunnel.volter.accounts.admin_tokens_create', 'volter_accounts', 'POST /admin/accounts/:slug/tokens creates a service token', 'api', 'niche'),
1394
+ todo('tunnel.volter.accounts.admin_tokens_revoke', 'volter_accounts', 'DELETE /admin/accounts/:slug/tokens/:tokenId revokes a service token', 'api', 'niche'),
1395
+ todo('tunnel.volter.accounts.admin_limits_patch', 'volter_accounts', 'PATCH /admin/accounts/:slug/limits updates account limits', 'api', 'niche'),
1396
+ todo('tunnel.volter.accounts.admin_suspend', 'volter_accounts', 'POST /admin/accounts/:slug/suspend suspends an account', 'api', 'niche'),
1397
+ todo('tunnel.volter.accounts.admin_resume', 'volter_accounts', 'POST /admin/accounts/:slug/resume resumes an account', 'api', 'niche'),
1398
+ todo('tunnel.volter.accounts.admin_usage', 'volter_accounts', 'GET /admin/accounts/:slug/usage returns one account usage snapshot', 'api', 'niche'),
1399
+ todo('tunnel.volter.usage.metering', 'volter_usage', 'Request/WebSocket/byte/second credit metering', 'api', 'common'),
1400
+ todo('tunnel.volter.usage.admin_summary', 'volter_usage', 'GET /admin/usage returns the fleet usage summary', 'api', 'niche'),
1401
+ todo('tunnel.volter.management.report_create', 'volter_management', 'POST /report submits a public abuse report', 'api', 'niche'),
1402
+ todo('tunnel.volter.management.reports_admin_list', 'volter_management', 'GET /admin/reports lists abuse reports as root', 'api', 'niche'),
1403
+ todo('tunnel.volter.signup.github_token', 'volter_signup', 'POST /signup/github signs up using a GitHub access token', 'api', 'niche'),
1404
+ todo('tunnel.volter.signup.github_gist_start', 'volter_signup', 'POST /signup/github/gist/start starts gist-based identity verification', 'api', 'niche'),
1405
+ todo('tunnel.volter.signup.github_gist_verify', 'volter_signup', 'POST /signup/github/gist/verify completes gist-based identity verification', 'api', 'niche'),
1406
+ todo('tunnel.volter.signup.waitlist_create', 'volter_signup', 'POST /waitlist submits a public waitlist request', 'api', 'niche'),
1407
+ todo('tunnel.volter.signup.waitlist_admin_list', 'volter_signup', 'GET /admin/waitlist lists waitlist requests as root', 'api', 'niche'),
1408
+ todo('tunnel.volter.signup.waitlist_admin_remove', 'volter_signup', 'DELETE /admin/waitlist/:githubUser removes a waitlist entry', 'api', 'niche'),
1409
+ todo('tunnel.volter.inspector.list', 'volter_inspector', 'GET /__volter_inspect returns the owner-authenticated live request ring', 'api', 'niche'),
1410
+ todo('tunnel.volter.inspector.replay', 'volter_inspector', 'POST /__volter_replay reissues a captured request', 'api', 'niche'),
1411
+ todo('tunnel.volter.management.landing', 'volter_management', 'GET / serves the owned relay public landing surface', 'api', 'niche'),
1412
+ todo('tunnel.volter.management.docs', 'volter_management', 'GET /docs serves the owned relay documentation surface', 'api', 'niche'),
1413
+
1414
+ // The owned protocol's authoritative 15 message discriminators. Implemented frames have
1415
+ // transport proofs above; every remaining frame stays visible here instead of disappearing
1416
+ // from the denominator behind broader feature labels.
1417
+ done('tunnel.volter.protocol.register', 'volter_control', 'Protocol frame: register', 'api', 'core', () => withRoot(async (root) => {
1418
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'frame-register', { authRequired: false });
1419
+ try {
1420
+ const resource = projectResources('tunnel', root).find((candidate) => candidate.id === 'relay:frame-register');
1421
+ return control.tunnelId === 'frame-register' && resource?.connected === true
1422
+ && listActions('tunnel', root).some((action) => action.operation === 'relay.register' && action.subject.id === 'relay:frame-register');
1423
+ } finally { control.socket.close(); relay.stop(); }
1424
+ })),
1425
+ done('tunnel.volter.protocol.registered', 'volter_control', 'Protocol frame: registered', 'api', 'core', () => withRoot(async (root) => {
1426
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'frame-registered', { authRequired: false });
1427
+ try { return control.tunnelId === 'frame-registered' && control.url === `${relay.url}/__twin/tunnels/frame-registered`; }
1428
+ finally { control.socket.close(); relay.stop(); }
1429
+ })),
1430
+ done('tunnel.volter.protocol.request', 'volter_http', 'Protocol frame: request', 'api', 'core', () => withRoot(async (root) => (await protocolRoundtrip(root)).body.marker === 'genuine-origin')),
1431
+ done('tunnel.volter.protocol.response', 'volter_http', 'Protocol frame: response', 'api', 'core', () => withRoot(async (root) => (await protocolRoundtrip(root)).response.status === 201)),
1432
+ done('tunnel.volter.protocol.response_start', 'volter_http', 'Protocol frame: response-start', 'api', 'core', () => withRoot(async (root) => {
1433
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'frame-start', { authRequired: false });
1434
+ try {
1435
+ const frame = nextSocketMessage(control.socket, 'request'); const p = fetch(`${control.url}/x`); const req = await frame;
1436
+ control.socket.send(JSON.stringify({ type: 'response-start', reqId: req.reqId, status: 206, headers: {} }));
1437
+ control.socket.send(JSON.stringify({ type: 'response-chunk', reqId: req.reqId, data: btoa('x') }));
1438
+ control.socket.send(JSON.stringify({ type: 'response-end', reqId: req.reqId }));
1439
+ const res = await p; await res.arrayBuffer();
1440
+ // The frame is ACCEPTED — and the three reliability capabilities that depend on COMMITTING
1441
+ // the head at this point are still honestly `todo`. That list shrank by one when
1442
+ // `visitor_disconnect_abort` was built (it never needed a committed head: a visitor hang-up
1443
+ // before `response-start` is observable on this runtime), which is exactly the kind of
1444
+ // silent staleness this cross-check exists to force.
1445
+ const reliabilityTodos = ['tunnel.volter.http.streaming', 'tunnel.volter.http.stream_backpressure', 'tunnel.volter.http.stream_cancel_abort'];
1446
+ return res.status === 206 && reliabilityTodos.every((id) => {
1447
+ const capability = TUNNEL_CAPABILITIES.find((candidate) => candidate.id === id);
1448
+ return capability?.expected === 'todo' && capability.verify === undefined && capability.tier === 'core';
1449
+ });
1450
+ }
1451
+ finally { control.socket.close(); relay.stop(); }
1452
+ })),
1453
+ done('tunnel.volter.protocol.response_chunk', 'volter_http', 'Protocol frame: response-chunk', 'api', 'core', () => withRoot(async (root) => {
1454
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'frame-chunk', { authRequired: false });
1455
+ try { const frame = nextSocketMessage(control.socket, 'request'); const p = fetch(`${control.url}/x`); const req = await frame; control.socket.send(JSON.stringify({ type: 'response-start', reqId: req.reqId, status: 200, headers: {} })); control.socket.send(JSON.stringify({ type: 'response-chunk', reqId: req.reqId, data: btoa('chunk') })); control.socket.send(JSON.stringify({ type: 'response-end', reqId: req.reqId })); const res = await p; return await res.text() === 'chunk'; }
1456
+ finally { control.socket.close(); relay.stop(); }
1457
+ })),
1458
+ done('tunnel.volter.protocol.response_end', 'volter_http', 'Protocol frame: response-end', 'api', 'core', () => withRoot(async (root) => {
1459
+ const relay = createTunnelTwinServer({ root }); const control = await openControl(relay.url, 'frame-end', { authRequired: false });
1460
+ try { const frame = nextSocketMessage(control.socket, 'request'); const p = fetch(`${control.url}/x`); const req = await frame; control.socket.send(JSON.stringify({ type: 'response-start', reqId: req.reqId, status: 200, headers: {} })); control.socket.send(JSON.stringify({ type: 'response-end', reqId: req.reqId })); const res = await p; return (await res.arrayBuffer()).byteLength === 0; }
1461
+ finally { control.socket.close(); relay.stop(); }
1462
+ })),
1463
+ done('tunnel.volter.protocol.request_abort', 'volter_http', 'Protocol frame: request-abort', 'api', 'core', () => withRoot(async (root) => {
1464
+ // A request that ends badly must STOP the client, not just answer the visitor. The client's
1465
+ // own handler destroys the local request on this frame, so a relay that forgot to send it
1466
+ // would leave the local server producing a response nobody will ever read.
1467
+ // 400ms, not 120: §9 ranked the old budget the flakiest thing in this file — the second
1468
+ // half needs a whole fetch/frame/response round trip inside it while the catalog's other T0s
1469
+ // run alongside. It fails RED when missed (504 ≠ 200), so this only buys headroom.
1470
+ const relay = createTunnelTwinServer({ root, requestTimeoutMs: 400 });
1471
+ const control = await openControl(relay.url, 'frame-abort', { authRequired: false });
1472
+ try {
1473
+ // (1) The TIMEOUT path: the client never answers, the relay gives up.
1474
+ const timedOutFrame = nextSocketMessage(control.socket, 'request');
1475
+ const timedOut = fetch(`${control.url}/never-answered`);
1476
+ const first = await timedOutFrame;
1477
+ const abortOnTimeout = await nextSocketMessage(control.socket, 'request-abort');
1478
+ const timedOutResponse = await timedOut;
1479
+ const timedOutBody = await timedOutResponse.json() as { error?: string };
1480
+
1481
+ // (2) The COMPLETED path: a request the client answers must NOT be aborted. Without this
1482
+ // half, a relay that sent `request-abort` after every request would pass the first half.
1483
+ const okFrame = nextSocketMessage(control.socket, 'request');
1484
+ const okResponse = fetch(`${control.url}/answered`);
1485
+ const second = await okFrame;
1486
+ control.socket.send(JSON.stringify({ type: 'response', reqId: second.reqId, status: 200, headers: {}, body: btoa('done') }));
1487
+ const settled = await okResponse;
1488
+ const body = await settled.text();
1489
+ const strayAbort = await Promise.race([
1490
+ nextSocketMessage(control.socket, 'request-abort', 250).then(() => true).catch(() => false),
1491
+ new Promise<boolean>((resolve) => setTimeout(() => resolve(false), 300)),
1492
+ ]);
1493
+ return (
1494
+ abortOnTimeout.reqId === first.reqId &&
1495
+ UUID_PATTERN.test(String(first.reqId)) &&
1496
+ timedOutResponse.status === 504 &&
1497
+ timedOutBody.error === 'Tunnel request timed out' &&
1498
+ settled.status === 200 && body === 'done' &&
1499
+ strayAbort === false
1500
+ );
1501
+ } finally { control.socket.close(); relay.stop(); }
1502
+ })),
1503
+ done('tunnel.volter.protocol.error', 'volter_control', 'Protocol frame: error', 'api', 'core', () => withRoot(async (root) => {
1504
+ const relay = createTunnelTwinServer({ root }); const socket = new WebSocket(`${relay.url.replace(/^http/, 'ws')}/ws`);
1505
+ try {
1506
+ await new Promise<void>((resolve, reject) => {
1507
+ socket.addEventListener('open', () => resolve(), { once: true });
1508
+ socket.addEventListener('error', () => reject(new Error('error-frame socket failed')), { once: true });
1509
+ });
1510
+ const rejected = nextSocketMessage(socket, 'error');
1511
+ socket.send(JSON.stringify({ type: 'register', tunnelId: 'frame-error' }));
1512
+ const error = await rejected;
1513
+ return error.type === 'error' && error.fatal === true && listActions('tunnel', root).length === 0;
1514
+ } finally { socket.close(); relay.stop(); }
1515
+ })),
1516
+ done('tunnel.volter.protocol.ws_ready', 'volter_websocket', 'Protocol frame: ws-ready', 'api', 'core', () => withRoot(async (root) => {
1517
+ // A browser usually speaks FIRST (a client library sends its hello immediately), and that
1518
+ // happens while the client is still dialling its local server. `ws-ready` is the frame that
1519
+ // says the bridge exists — so what it must prove is that frames sent BEFORE it are delivered
1520
+ // after it, in order, rather than dropped into a bridge that did not exist yet.
1521
+ const bridge = await openWsBridge(root, 'hold');
1522
+ try {
1523
+ const { socket: visitor } = await bridge.visitor('/ready');
1524
+ visitor.send('early-one');
1525
+ visitor.send('early-two');
1526
+ await new Promise((resolve) => setTimeout(resolve, 50));
1527
+ const beforeReady = bridge.frames.filter((frame) => frame.type === 'ws-message');
1528
+ bridge.release();
1529
+ const first = await nextVisitorFrame(visitor);
1530
+ const second = await nextVisitorFrame(visitor);
1531
+ visitor.close();
1532
+ return (
1533
+ // nothing was relayed while the bridge was still coming up…
1534
+ beforeReady.length === 0 &&
1535
+ // …and then BOTH queued frames arrive, in the order the browser sent them
1536
+ 'data' in first && first.data === 'echo:/ready:early-one' &&
1537
+ 'data' in second && second.data === 'echo:/ready:early-two'
1538
+ );
1539
+ } finally { bridge.stop(); }
1540
+ })),
1541
+ done('tunnel.volter.protocol.ws_error', 'volter_websocket', 'Protocol frame: ws-error', 'api', 'core', () => withRoot(async (root) => {
1542
+ // The client could not reach the local server. The browser must be TOLD — a bridge that
1543
+ // silently stayed open would leave a page waiting forever on a socket that goes nowhere.
1544
+ const bridge = await openWsBridge(root, 'refuse');
1545
+ try {
1546
+ // Opened by hand rather than through `visitor()`: the refusal can land before the browser's
1547
+ // own `open` fires, so the outcome to wait for is "opened OR closed", not "opened".
1548
+ const visitor = new WebSocket(`${bridge.control.url.replace(/^http/, 'ws')}/refused`);
1549
+ const closed = await new Promise<{ code: number; reason: string } | 'still-open'>((resolve, reject) => {
1550
+ const timer = setTimeout(() => reject(new Error('the refused visitor socket was never closed')), 3_000);
1551
+ visitor.addEventListener('close', (event) => { clearTimeout(timer); resolve({ code: event.code, reason: event.reason }); }, { once: true });
1552
+ });
1553
+ const upgrade = bridge.frames.find((frame) => frame.type === 'ws-upgrade');
1554
+ return (
1555
+ upgrade !== undefined &&
1556
+ closed !== 'still-open' &&
1557
+ // 1011 "internal error" with the client's OWN message — the browser learns why, and the
1558
+ // relay does not invent a reason of its own.
1559
+ closed.code === 1011 &&
1560
+ closed.reason === 'ECONNREFUSED dialling local server'
1561
+ );
1562
+ } finally { bridge.stop(); }
1563
+ })),
1564
+ done('tunnel.volter.protocol.ws_message', 'volter_websocket', 'Protocol frame: ws-message', 'api', 'core', () => withRoot(async (root) => {
1565
+ const bridge = await openWsBridge(root);
1566
+ try {
1567
+ const { socket: visitor, upgrade } = await bridge.visitor('/frames');
1568
+ visitor.send(new Uint8Array([9, 8, 7]));
1569
+ const reversed = await nextVisitorFrame(visitor);
1570
+ const relayed = bridge.frames.filter((frame) => frame.type === 'ws-message');
1571
+ visitor.close();
1572
+ // The frame's own fields: correlated by connId, payload base64, and the `binary` flag the
1573
+ // client uses to decide the local frame type. A relay that dropped `binary` would turn
1574
+ // every binary frame into text without any error to notice.
1575
+ return (
1576
+ relayed.length === 1 &&
1577
+ relayed[0]!.connId === upgrade.connId &&
1578
+ relayed[0]!.binary === true &&
1579
+ Buffer.from(String(relayed[0]!.data), 'base64').toString('hex') === '090807' &&
1580
+ 'closed' in reversed === false &&
1581
+ 'data' in reversed && reversed.data instanceof ArrayBuffer &&
1582
+ [...new Uint8Array(reversed.data)].join(',') === '7,8,9'
1583
+ );
1584
+ } finally { bridge.stop(); }
1585
+ })),
1586
+ done('tunnel.volter.protocol.ws_close', 'volter_websocket', 'Protocol frame: ws-close', 'api', 'common', () => withRoot(async (root) => {
1587
+ const bridge = await openWsBridge(root);
1588
+ try {
1589
+ const { socket: visitor, upgrade } = await bridge.visitor('/closing');
1590
+ visitor.close(4200, 'done');
1591
+ const relayed = await nextSocketMessage(bridge.control.socket, 'ws-close');
1592
+ // …and a SECOND close is not sent when the close came from the client's own side: the
1593
+ // relay would otherwise echo a close back at the party that sent it.
1594
+ const second = await bridge.visitor('/closing2');
1595
+ const before = bridge.frames.filter((frame) => frame.type === 'ws-close').length;
1596
+ const closing = nextVisitorFrame(second.socket);
1597
+ bridge.control.socket.send(JSON.stringify({ type: 'ws-close', connId: second.upgrade.connId, code: 1000 }));
1598
+ await closing;
1599
+ await new Promise((resolve) => setTimeout(resolve, 50));
1600
+ return (
1601
+ relayed.connId === upgrade.connId && relayed.code === 4200 &&
1602
+ bridge.frames.filter((frame) => frame.type === 'ws-close').length === before
1603
+ );
1604
+ } finally { bridge.stop(); }
1605
+ })),
1606
+ done('tunnel.volter.protocol.ws_upgrade', 'volter_websocket', 'Protocol frame: ws-upgrade', 'api', 'core', () => withRoot(async (root) => {
1607
+ const bridge = await openWsBridge(root);
1608
+ try {
1609
+ const { socket: visitor, upgrade } = await bridge.visitor('/upgrade/path?x=1');
1610
+ visitor.close();
1611
+ // The frame the client dials from: a fresh connId, the TUNNELLED path (query included),
1612
+ // and the browser's own handshake headers — which is how the client forwards a
1613
+ // subprotocol and an auth cookie to the local server.
1614
+ return (
1615
+ UUID_PATTERN.test(String(upgrade.connId)) &&
1616
+ upgrade.path === '/upgrade/path?x=1' &&
1617
+ typeof upgrade.headers === 'object' &&
1618
+ typeof upgrade.headers['sec-websocket-key'] === 'string' &&
1619
+ upgrade.headers['x-forwarded-for'] === '0.0.0.0' &&
1620
+ // one connId per socket — two browsers on one tunnel must not share a bridge
1621
+ (await (async () => {
1622
+ const other = await bridge.visitor('/upgrade/path?x=1');
1623
+ other.socket.close();
1624
+ return other.upgrade.connId !== upgrade.connId;
1625
+ })())
1626
+ );
1627
+ } finally { bridge.stop(); }
1628
+ })),
1629
+ done('tunnel.volter.websocket.auth_gate', 'volter_auth', 'A browser WebSocket upgrade passes the SAME auth gates the HTTP path does — an unauthenticated upgrade never reaches a bridge', 'api', 'common', () => withRoot(async (root) => {
1630
+ // The gate has to bite BEFORE `server.upgrade`, or the relay would have an unauthenticated
1631
+ // hole sitting beside an authenticated door. `refused === 'closed'` is what proves the
1632
+ // ORDER, and it needs no timing to do it: a relay that upgraded first would fire `open` on
1633
+ // that socket before any close, and the promise below would resolve `'opened'`. The frame
1634
+ // counts are the second, independent tooth — `afterAuth === 1` is an exact equality, so a
1635
+ // stray `ws-upgrade` from the refused attempt reddens it. (§9 was right that the original
1636
+ // comment credited the frame count for what the close proves, and that the negative half
1637
+ // deserved the settle the positive one had.)
1638
+ const relay = createTunnelTwinServer({ root });
1639
+ // `authRequired` defaults to the owned relay's own default (true) — deliberately not passed.
1640
+ const control = await openControl(relay.url, 'ws-auth');
1641
+ try {
1642
+ const frames: Array<Record<string, any>> = [];
1643
+ control.socket.addEventListener('message', (event) => frames.push(JSON.parse(String(event.data)) as Record<string, any>));
1644
+ const anonymous = new WebSocket(`${control.url.replace(/^http/, 'ws')}/private`);
1645
+ const refused = await new Promise<string>((resolve) => {
1646
+ const timer = setTimeout(() => resolve('still-open'), 2_000);
1647
+ anonymous.addEventListener('open', () => { clearTimeout(timer); resolve('opened'); }, { once: true });
1648
+ anonymous.addEventListener('close', () => { clearTimeout(timer); resolve('closed'); }, { once: true });
1649
+ anonymous.addEventListener('error', () => { clearTimeout(timer); resolve('closed'); }, { once: true });
1650
+ });
1651
+ await new Promise((resolve) => setTimeout(resolve, 50));
1652
+ const afterRefusal = frames.filter((frame) => frame.type === 'ws-upgrade').length;
1653
+ // …and the SAME upgrade with the relay's own minted, tunnel-bound token is accepted.
1654
+ const token = relay.mintToken(control.tunnelId);
1655
+ // THE 101's OWN BYTES: a query-token upgrade must hand back the same `__volter_auth`
1656
+ // cookie the identical HTTP request does, so the page's later requests are authenticated
1657
+ // without re-carrying the token. Bun's WebSocket client cannot see a response header at
1658
+ // all, so this is read off the wire — §9 flagged the cookie as shipped-with-zero-coverage.
1659
+ const handshake = await readUpgradeHandshake(`${control.url.replace(/^http/, 'ws')}/private?__volter_token=${encodeURIComponent(token)}`);
1660
+ const authorised = new WebSocket(`${control.url.replace(/^http/, 'ws')}/private?__volter_token=${encodeURIComponent(token)}`);
1661
+ const accepted = await new Promise<string>((resolve) => {
1662
+ const timer = setTimeout(() => resolve('still-open'), 3_000);
1663
+ authorised.addEventListener('open', () => { clearTimeout(timer); resolve('opened'); }, { once: true });
1664
+ authorised.addEventListener('close', () => { clearTimeout(timer); resolve('closed'); }, { once: true });
1665
+ authorised.addEventListener('error', () => { clearTimeout(timer); resolve('closed'); }, { once: true });
1666
+ });
1667
+ await new Promise((resolve) => setTimeout(resolve, 50));
1668
+ const afterAuth = frames.filter((frame) => frame.type === 'ws-upgrade').length;
1669
+ authorised.close();
1670
+ return (
1671
+ refused === 'closed' &&
1672
+ afterRefusal === 0 &&
1673
+ accepted === 'opened' &&
1674
+ afterAuth === 2 &&
1675
+ handshake.status === 101 &&
1676
+ handshake.headers['set-cookie']?.startsWith('__volter_auth=') === true &&
1677
+ handshake.headers['set-cookie']?.includes('HttpOnly') === true
1678
+ );
1679
+ } finally { control.socket.close(); relay.stop(); }
1680
+ })),
1681
+ done('tunnel.volter.websocket.owner_scoping', 'volter_websocket', 'A control socket may only drive the bridges it owns; another tunnel\'s connId is refused', 'api', 'common', () => withRoot(async (root) => {
1682
+ const bridge = await openWsBridge(root);
1683
+ try {
1684
+ const { socket: visitor, upgrade } = await bridge.visitor('/scoped');
1685
+ // A SECOND registered client on the same relay, guessing the first tunnel's connId. If the
1686
+ // relay correlated on connId alone, this would drive somebody else's browser socket.
1687
+ const intruder = await openControl(bridge.relay.url, 'intruder', { authRequired: false });
1688
+ try {
1689
+ const refused = nextSocketMessage(intruder.socket, 'error');
1690
+ intruder.socket.send(JSON.stringify({ type: 'ws-message', connId: upgrade.connId, data: btoa('stolen'), binary: false }));
1691
+ const error = await refused;
1692
+ // …and the victim's socket saw nothing.
1693
+ // ONE wait, not a race whose second leg could never win (§9: the 250ms leg was dead code
1694
+ // behind a 200ms one). A leak that arrived later than this would still read 'quiet', which
1695
+ // is why the ERROR FRAME above — which is immediate and unconditional — is what actually
1696
+ // proves the refusal; this is the corroborating half.
1697
+ const quiet = await nextVisitorFrame(visitor, 300).then(() => 'leaked' as const).catch(() => 'quiet' as const);
1698
+ visitor.close();
1699
+ return String(error.message).includes('not owned by this control socket') && quiet === 'quiet';
1700
+ } finally { intruder.socket.close(); }
1701
+ } finally { bridge.stop(); }
1702
+ })),
1703
+ todo('tunnel.volter.protocol.quota', 'volter_control', 'Protocol frame: quota', 'api', 'common'),
1704
+ done('tunnel.volter.control.protocol_census', 'volter_control', 'Every authoritative owned relay message discriminator has exactly one explicit protocol capability row', 'api', 'core', async () => {
1705
+ const declared = TUNNEL_CAPABILITIES
1706
+ .filter((capability) => capability.id.startsWith('tunnel.volter.protocol.'))
1707
+ .map((capability) => capability.id.slice('tunnel.volter.protocol.'.length).replaceAll('_', '-'))
1708
+ .sort();
1709
+ return JSON.stringify(declared) === JSON.stringify([...TUNNEL_PROTOCOL_MESSAGE_TYPES].sort());
1710
+ }),
1711
+
1712
+ // Connector + safety.
1713
+ done('tunnel.connector.pull_status', 'connector', 'Pull the exact owned relay health shape through an injected client and fold it into state', 'connector', 'core', () => withRoot(async (root) => {
1714
+ const result = await syncTunnelFromReal(async () => ({ status: 200, body: { ok: true, relay: 'cloudflare-do' } }), { root, occurredAt: AT });
1715
+ const resource = projectResources('tunnel', root).find((x) => x.id === 'relay:default');
1716
+ return result.observed === 1 && result.deltasAppended === 1 && resource?.relay === 'cloudflare-do' && resource?.tunnels === undefined;
1717
+ })),
1718
+ done('tunnel.connector.pull_idempotent', 'connector', 'Identical status re-pull appends no delta', 'connector', 'common', () => withRoot(async (root) => {
1719
+ const client = async () => ({ status: 200, body: { ok: true, relay: 'cloudflare-do' } });
1720
+ await syncTunnelFromReal(client, { root, occurredAt: AT });
1721
+ return (await syncTunnelFromReal(client, { root, occurredAt: AT })).deltasAppended === 0;
1722
+ })),
1723
+ done('tunnel.connector.refusal_not_empty', 'connector', 'A refused status read throws instead of overwriting state with an empty relay', 'connector', 'core', () => withRoot(async (root) => {
1724
+ await syncTunnelFromReal(async () => ({ status: 200, body: { ok: true, relay: 'cloudflare-do' } }), { root, occurredAt: AT });
1725
+ const beforeResources = JSON.stringify(projectResources('tunnel', root));
1726
+ const beforeActions = listActions('tunnel', root).length;
1727
+ try {
1728
+ await syncTunnelFromReal(async () => ({ status: 503, body: { error: 'down' } }), { root, occurredAt: '2026-01-02T00:00:00.000Z' });
1729
+ return false;
1730
+ } catch (error) {
1731
+ return String(error).includes('refused')
1732
+ && JSON.stringify(projectResources('tunnel', root)) === beforeResources
1733
+ && listActions('tunnel', root).length === beforeActions;
1734
+ }
1735
+ })),
1736
+ done('tunnel.connector.mapper', 'connector', 'Status mapper preserves the owned health identity without inventing a tunnel count', 'connector', 'common', async () => {
1737
+ const x = mapTunnelRelay({ ok: true, relay: 'cloudflare-do' }); return x.fields.ok === true && x.fields.relay === 'cloudflare-do' && x.fields.tunnels === undefined;
1738
+ }),
1739
+ done('tunnel.connector.exact_status_shape', 'connector', 'Pull refuses extra status fields that are not present in the owned public contract', 'connector', 'core', async () => {
1740
+ try { await syncTunnelFromReal(async () => ({ status: 200, body: { ok: true, relay: 'cloudflare-do', tunnels: 7 } })); return false; }
1741
+ catch (error) { return String(error).includes('no healthy relay'); }
1742
+ }),
1743
+ done('tunnel.connector.rate_budget_fail_closed', 'connector', 'Saturated client budget refuses before fetch', 'connector', 'common', () => withRoot(async (root) => {
1744
+ let calls = 0; const now = () => Date.parse(AT); const path = join(root, 'budget.json');
1745
+ const fake = (async () => { calls++; return new Response('{"ok":true,"relay":"x"}'); }) as unknown as typeof fetch;
1746
+ const execute = liveTunnelExecute('token', 'https://relay.test', { fetchImpl: fake, budget: new TunnelBudget({ path, now }) });
1747
+ const allowed = Math.floor(TUNNEL_BUDGET_CEILING / TUNNEL_CALL_WEIGHTS.other);
1748
+ for (let i = 0; i < allowed; i++) await execute('GET', '/api/status');
1749
+ try { await execute('GET', '/api/status'); return false; } catch (e) { return e instanceof TunnelBudgetError && calls === allowed; }
1750
+ })),
1751
+ done('tunnel.connector.rate_budget_persists', 'connector', 'Budget persists across client instances sharing a ledger', 'connector', 'common', () => withRoot(async (root) => {
1752
+ let calls = 0; const now = () => Date.parse(AT); const path = join(root, 'budget.json');
1753
+ const fake = (async () => { calls++; return new Response('{"ok":true,"relay":"x"}'); }) as unknown as typeof fetch;
1754
+ const allowed = Math.floor(TUNNEL_BUDGET_CEILING / TUNNEL_CALL_WEIGHTS.other);
1755
+ const first = liveTunnelExecute('token', 'https://relay.test', { fetchImpl: fake, budget: new TunnelBudget({ path, now }) });
1756
+ for (let i = 0; i < allowed; i++) await first('GET', '/api/status');
1757
+ const second = liveTunnelExecute('token', 'https://relay.test', { fetchImpl: fake, budget: new TunnelBudget({ path, now }) });
1758
+ try { await second('GET', '/api/status'); return false; } catch (e) { return e instanceof TunnelBudgetError && calls === allowed; }
1759
+ })),
1760
+ todo('tunnel.connector.push_public', 'connector', 'Push a local registration to a real provider under explicit operator confirmation', 'connector', 'common'),
1761
+ todo('tunnel.connector.pull_accounts', 'connector', 'Pull owned relay accounts/reservations/usage through admin APIs', 'connector', 'niche'),
1762
+ ];
1763
+
1764
+ export const TUNNEL_AREAS = [
1765
+ 'cloudflare_quick', 'cloudflare_managed', 'volter_control', 'volter_http',
1766
+ 'volter_websocket', 'volter_auth', 'volter_reservations', 'volter_accounts', 'volter_usage',
1767
+ 'volter_signup', 'volter_inspector', 'volter_management', 'connector',
1768
+ ] as const;
1769
+
1770
+ export function tunnelCapabilities(): Promise<CapabilityReport> { return checkCapabilities('tunnel', TUNNEL_CAPABILITIES); }