From 3274f7bea293d36047e556e8ec4d8186fa3673c6 Mon Sep 17 00:00:00 2001 From: Alex Lavaee Date: Thu, 22 Oct 2026 13:27:27 -0700 Subject: [PATCH] Upgrade Bun to 1.4.4 Bun 1.4.4 carries security fixes for TLS, WebSocket, Bun.SQL, fetch and the package manager. The CI, release and agent-verification workflows, the weekly React Effect review (recompiled with gh aw 0.86.2), mise.toml, packageManager, the application and E2E Docker images and the documentation now name 1.4.4. @types/bun has no 1.4.4 release yet, so the catalog takes 1.4.3 and an override supplies bun-types 1.4.4, the types published with this release. Those types add result metadata to Bun.SQL query results, so the migration test compares a plain copy of each result. Three behaviours changed under 1.4.4: - fetch now starts a network error's message with its code, so the connector printed "ECONNRESET: ECONNRESET: ..." when Chopin was unreachable. It names the code once again. - A pending `.rejects` matcher in bun test makes Bun.serve close a valid WebSocket as fragmented (oven-sh/bun#45805). The agent link's Stop and Resume test awaits the refusal before asserting it. Only that test pattern is affected. - Bun 1.4.4, like 1.4.2, reports ENETUNREACH as ECONNREFUSED in a route-free network namespace, so the conversation-plan worker's egress check keys its mapping on 1.4.4. The chopin CLI is compiled with the release workflow's Bun, so its next release embeds 1.4.4 and the connector's error wording fix. Assistant-model: Claude Opus 5.5 (fast) Assistant-workflow: inline (fast subagents) Assistant-verification: bun test passes with Bun 1.4.4 (6725 pass, 0 fail); the two failures it first showed pass on both 1.4.2 and 1.4.4 after the fixes Assistant-verification: the PostgreSQL contract, bun run types and bun run ci pass Assistant-verification: the application and design Docker images build on oven/bun:1.4.4, and the compiled CLI passes its bridge smoke test Assistant-verification: the connector, connection, machine, Planner attachment, launcher, restart, collaboration and setup E2E files pass (60 passed, 1 live test skipped) User-preference: Keep Bun on the latest security release Co-authored-by: Alex Lavaee --- .github/workflows/ci.yml | 2 +- .github/workflows/release-cli.yml | 2 +- .github/workflows/verify-agents.yml | 2 +- .../weekly-use-effect-review.lock.yml | 4 ++-- .github/workflows/weekly-use-effect-review.md | 2 +- AGENTS.md | 2 +- Dockerfile | 2 +- README.md | 2 +- apps/connector/src/connection.ts | 6 ++++- apps/server/src/harness/remote/link.test.ts | 6 ++++- .../src/storage/postgres/adapter.test.ts | 22 +++++++++---------- bun.lock | 9 +++++--- docs/chopin-cli-reference.md | 2 +- docs/self-hosting.md | 2 +- e2e/conversation-plan.Dockerfile | 2 +- e2e/design/Dockerfile | 2 +- e2e/design/README.md | 2 +- mise.toml | 2 +- package.json | 7 ++++-- scripts/conversation-plan-worker.ts | 4 ++-- 20 files changed, 49 insertions(+), 35 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d55819db..9a35f983a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ permissions: env: # Matches the version this is developed against. Bun's lockfile format and # its workspace catalogs are both young enough that "latest" is a variable. - BUN_VERSION: 1.4.2 + BUN_VERSION: 1.4.4 # Shard counts; keep each matrix below in step with its count. UNIT_SHARDS: 3 E2E_SHARDS: 12 diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index be0fcec3c..e2f0808fd 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -23,7 +23,7 @@ concurrency: permissions: {} env: - BUN_VERSION: 1.4.2 + BUN_VERSION: 1.4.4 jobs: build: diff --git a/.github/workflows/verify-agents.yml b/.github/workflows/verify-agents.yml index 4b42c6fd2..08d6f9659 100644 --- a/.github/workflows/verify-agents.yml +++ b/.github/workflows/verify-agents.yml @@ -12,7 +12,7 @@ permissions: contents: read env: - BUN_VERSION: 1.4.2 + BUN_VERSION: 1.4.4 jobs: agents: diff --git a/.github/workflows/weekly-use-effect-review.lock.yml b/.github/workflows/weekly-use-effect-review.lock.yml index 29779c784..1f35f65e6 100644 --- a/.github/workflows/weekly-use-effect-review.lock.yml +++ b/.github/workflows/weekly-use-effect-review.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"71a4478acc0f9a335f5aad09be0a56a3dc033b9140dee7c22612f7c123f3d415","body_hash":"bd1d56de5e3ff2f12864ebb0025aa53859f16742faaedf5ea7be03fe3ac4573c","compiler_version":"v0.86.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.79"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"a332ef854235e769dafc33453bd0a212cbce00451245f6e72bc058e7195efb19","body_hash":"bd1d56de5e3ff2f12864ebb0025aa53859f16742faaedf5ea7be03fe3ac4573c","compiler_version":"v0.86.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.79"}} # gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"6aab9e5b5c91c615506061f09bedd81a23babe3c","version":"v0.86.2"},{"repo":"oven-sh/setup-bun","sha":"0c5077e51419868618aeaa5fe8019c62421857d6","version":"v2.2.0"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.44","digest":"sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.44@sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44","digest":"sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44@sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44","digest":"sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44@sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.9","digest":"sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.9@sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.9.0","digest":"sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e","pinned_image":"ghcr.io/github/github-mcp-server:v1.9.0@sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e"}]} # This file was automatically generated by gh-aw (v0.86.2). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -411,7 +411,7 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: - bun-version: '1.4.2' + bun-version: '1.4.4' - name: Create gh-aw temp directory run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh" - name: Configure gh CLI for GitHub Enterprise diff --git a/.github/workflows/weekly-use-effect-review.md b/.github/workflows/weekly-use-effect-review.md index 1fc54da33..e51adc52a 100644 --- a/.github/workflows/weekly-use-effect-review.md +++ b/.github/workflows/weekly-use-effect-review.md @@ -14,7 +14,7 @@ permissions: runtimes: bun: - version: "1.4.2" + version: "1.4.4" steps: - name: Install repository dependencies diff --git a/AGENTS.md b/AGENTS.md index 2916966ac..3f3888ea2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -43,7 +43,7 @@ bun run docker:up # build and start app plus PostgreSQL locally bun run docker:down # tear down the local Compose project ``` -The repository pins Bun 1.4.2. `mise.toml` selects that version automatically for +The repository pins Bun 1.4.4. `mise.toml` selects that version automatically for contributors who use [mise](https://mise.jdx.dev); run `mise install` once. Keep the package metadata, `mise.toml`, Docker image, CI, and documentation synchronized when changing it. diff --git a/Dockerfile b/Dockerfile index 48aaa8a35..29d480e54 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -ARG BUN_VERSION=1.4.2 +ARG BUN_VERSION=1.4.4 FROM oven/bun:${BUN_VERSION} AS manifests WORKDIR /app diff --git a/README.md b/README.md index d9d0b7701..7886ebe82 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ and tool vocabulary remain optimized for planning. The development path requires: -- Bun 1.4.2; +- Bun 1.4.4; - Docker Engine with Docker Compose, used for PostgreSQL; - a GitHub App owned by the deployment; and - a GitHub account with push or administration access to a test repository and, diff --git a/apps/connector/src/connection.ts b/apps/connector/src/connection.ts index 4379dab10..09db39814 100644 --- a/apps/connector/src/connection.ts +++ b/apps/connector/src/connection.ts @@ -96,7 +96,11 @@ export function failureCause(error: unknown) { : typeof status === "string" ? status : undefined; - if (name) return detail ? `${name}: ${detail}` : name; + if (name) { + // Bun 1.4.4's fetch also starts its message with the code; name it once. + if (detail.startsWith(`${name}: `)) detail = detail.slice(name.length + 2); + return detail ? `${name}: ${detail}` : name; + } fallback ??= detail || undefined; current = current.cause; } diff --git a/apps/server/src/harness/remote/link.test.ts b/apps/server/src/harness/remote/link.test.ts index 0304dd566..c75f62977 100644 --- a/apps/server/src/harness/remote/link.test.ts +++ b/apps/server/src/harness/remote/link.test.ts @@ -1222,7 +1222,11 @@ describe("Agent connection protocol", () => { }); cleanups.push(() => session.doDestroy()); await planner.control!("stop", "run-1"); - await expect(planner.control!("resume")).rejects.toThrow("nothing to resume"); + // Bun 1.4.4's pending `.rejects` matcher makes Bun.serve close a valid socket as + // fragmented (oven-sh/bun#45805), so the refusal is awaited before it is asserted. + let refusal = await planner.control!("resume").catch((error: unknown) => error); + expect(refusal).toBeInstanceOf(Error); + expect((refusal as Error).message).toContain("nothing to resume"); expect(controls).toEqual([{ type: "stop", run: "run-1" }, { type: "resume", run: undefined }]); await session.doDestroy(); expect(planner.control).toBeUndefined(); diff --git a/apps/server/src/storage/postgres/adapter.test.ts b/apps/server/src/storage/postgres/adapter.test.ts index 2a0eb0209..cf17e44fe 100644 --- a/apps/server/src/storage/postgres/adapter.test.ts +++ b/apps/server/src/storage/postgres/adapter.test.ts @@ -1015,17 +1015,17 @@ if (url) { "026_workflow_run_stages", "027_decision_answers", ]); - expect(await sql<{ table: string | null }[]>`SELECT to_regclass('channel_slugs') AS table`) - .toEqual([ - { table: "channel_slugs" }, - ]); - expect(await sql<{ table: string | null }[]>`SELECT to_regclass('user_navigation') AS table`) - .toEqual([ - { table: "user_navigation" }, - ]); - expect( - await sql<{ table: string | null }[]>`SELECT to_regclass('research_workspaces') AS table`, - ).toEqual([{ table: "research_workspaces" }]); + expect([ + ...await sql<{ table: string | null }[]>`SELECT to_regclass('channel_slugs') AS table`, + ]).toEqual([{ table: "channel_slugs" }]); + expect([ + ...await sql<{ table: string | null }[]>`SELECT to_regclass('user_navigation') AS table`, + ]).toEqual([{ table: "user_navigation" }]); + expect([ + ...await sql< + { table: string | null }[] + >`SELECT to_regclass('research_workspaces') AS table`, + ]).toEqual([{ table: "research_workspaces" }]); } finally { await sql.unsafe(`DROP SCHEMA IF EXISTS "${schema}" CASCADE`).simple(); await sql.close(); diff --git a/bun.lock b/bun.lock index b39d178a5..4e1ced215 100644 --- a/bun.lock +++ b/bun.lock @@ -297,9 +297,12 @@ "mdast-util-to-markdown@2.1.2": "patches/mdast-util-to-markdown@2.1.2.patch", "@mdxeditor/editor@4.1.0": "patches/@mdxeditor%2Feditor@4.1.0.patch", }, + "overrides": { + "bun-types": "1.4.4", + }, "catalogs": { "bun": { - "@types/bun": "1.4.2", + "@types/bun": "1.4.3", }, "copilot": { "@github/copilot": "1.0.80", @@ -1163,7 +1166,7 @@ "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], - "@types/bun": ["@types/bun@1.4.2", "", { "dependencies": { "bun-types": "1.4.2" } }, "sha512-GimotNn7+ZV0uVArItBbriZsR1oNf0+WTzPkdcFrzShI7k2norL0uzEaJT8T33dWr7O/c9ZDuAFQrctKCi72oQ=="], + "@types/bun": ["@types/bun@1.4.3", "", { "dependencies": { "bun-types": "1.4.3" } }, "sha512-N67Pqy8JXbAY/j0tNraS3V5mubGvc6rrrNDmDCtZLlFzccbUJPDb0tvgUBC5q4m8ybkP93Jcn1QB+RYQ6PvBhw=="], "@types/d3": ["@types/d3@7.4.3", "", { "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", "@types/d3-brush": "*", "@types/d3-chord": "*", "@types/d3-color": "*", "@types/d3-contour": "*", "@types/d3-delaunay": "*", "@types/d3-dispatch": "*", "@types/d3-drag": "*", "@types/d3-dsv": "*", "@types/d3-ease": "*", "@types/d3-fetch": "*", "@types/d3-force": "*", "@types/d3-format": "*", "@types/d3-geo": "*", "@types/d3-hierarchy": "*", "@types/d3-interpolate": "*", "@types/d3-path": "*", "@types/d3-polygon": "*", "@types/d3-quadtree": "*", "@types/d3-random": "*", "@types/d3-scale": "*", "@types/d3-scale-chromatic": "*", "@types/d3-selection": "*", "@types/d3-shape": "*", "@types/d3-time": "*", "@types/d3-time-format": "*", "@types/d3-timer": "*", "@types/d3-transition": "*", "@types/d3-zoom": "*" } }, "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww=="], @@ -1343,7 +1346,7 @@ "buffer-image-size": ["buffer-image-size@0.6.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ=="], - "bun-types": ["bun-types@1.4.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-bxV1FgK7yBIzjRe5zBozIM4Bem11ZJcCXSrjWRG3YWLt8yFDePu4cLjpebO8OvPeIE9trbyPF4fuj3Cia4Fj3w=="], + "bun-types": ["bun-types@1.4.4", "", { "dependencies": { "@types/node": "*", "undici-types": "*" } }, "sha512-yjrJh5oGX7mMPKGd19YXyIjmEuj4G4zNC30bs7PM9Az7NQ3ndF3j6hbeRdvJTRQEhJ/FYQwW0a2moweEi2hMxQ=="], "bundle-name": ["bundle-name@4.1.1", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-DdH81/zPLVS11EUgWq3tEu/xn+EzljlMYooDNdzWEnFha3R3NBMpMV1UqYIpjYHV/SgpFKMIX1Oh7o06SjM/oA=="], diff --git a/docs/chopin-cli-reference.md b/docs/chopin-cli-reference.md index f46018c40..6aa07cca8 100644 --- a/docs/chopin-cli-reference.md +++ b/docs/chopin-cli-reference.md @@ -68,7 +68,7 @@ releases are made. ## Run without installing Every Chopin server also serves the connector as one script at -`/connector.js`. It needs [Bun](https://bun.sh) 1.4.2. This is the command +`/connector.js`. It needs [Bun](https://bun.sh) 1.4.4. This is the command Chopin shows when no local agent is connected: ```sh diff --git a/docs/self-hosting.md b/docs/self-hosting.md index a4527e92b..f680bc9a2 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -256,7 +256,7 @@ headers. ## Prerequisites -- Docker for the application image, or Bun 1.4.2 for a source deployment. +- Docker for the application image, or Bun 1.4.4 for a source deployment. - A reachable PostgreSQL database and credentials with schema migration access. - A stable DNS name with TLS termination and WebSocket proxying. - Outbound HTTPS access to GitHub and the selected harness's model provider diff --git a/e2e/conversation-plan.Dockerfile b/e2e/conversation-plan.Dockerfile index dbd1a322b..a5093f931 100644 --- a/e2e/conversation-plan.Dockerfile +++ b/e2e/conversation-plan.Dockerfile @@ -1,4 +1,4 @@ -FROM oven/bun:1.4.2 AS bun +FROM oven/bun:1.4.4 AS bun FROM mcr.microsoft.com/playwright:v1.62.1-noble@sha256:dcc5531e97840b9b5e794f2814476b21571c5124a3fca2267d73041f56e7580e COPY --from=bun /usr/local/bin/bun /usr/local/bin/bun WORKDIR /work diff --git a/e2e/design/Dockerfile b/e2e/design/Dockerfile index b8a8aa300..08fa8702c 100644 --- a/e2e/design/Dockerfile +++ b/e2e/design/Dockerfile @@ -1,4 +1,4 @@ -FROM oven/bun:1.4.2 AS bun +FROM oven/bun:1.4.4 AS bun FROM mcr.microsoft.com/playwright:v1.62.1-noble@sha256:dcc5531e97840b9b5e794f2814476b21571c5124a3fca2267d73041f56e7580e COPY --from=bun /usr/local/bin/bun /usr/local/bin/bun WORKDIR /work diff --git a/e2e/design/README.md b/e2e/design/README.md index b2fbbeeea..84091f982 100644 --- a/e2e/design/README.md +++ b/e2e/design/README.md @@ -1,7 +1,7 @@ # Rendered design checks `bun run design:browser` builds and runs a disposable Linux amd64 container with -Bun 1.4.2 and a digest-pinned Playwright 1.62.1 Noble image. It installs from the +Bun 1.4.4 and a digest-pinned Playwright 1.62.1 Noble image. It installs from the frozen lockfile, starts the real `/design-audit` development route and runs Chromium. Docker is required. No database, GitHub login, API key, host port or paid agent is used. This is an optional visual review command. Screenshot differences and exact diff --git a/mise.toml b/mise.toml index 39ab7e1e6..637ae5899 100644 --- a/mise.toml +++ b/mise.toml @@ -1,2 +1,2 @@ [tools] -bun = "1.4.2" +bun = "1.4.4" diff --git a/package.json b/package.json index 3914df95c..3fdbe59dd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "chopin", "private": true, - "packageManager": "bun@1.4.2", + "packageManager": "bun@1.4.4", "type": "module", "scripts": { "dev": "bun scripts/dev.ts", @@ -42,6 +42,9 @@ "postcss-value-parser": "4.2.0", "yaml": "2.9.0" }, + "overrides": { + "bun-types": "1.4.4" + }, "patchedDependencies": { "@mdxeditor/editor@4.1.0": "patches/@mdxeditor%2Feditor@4.1.0.patch", "mdast-util-to-markdown@2.1.2": "patches/mdast-util-to-markdown@2.1.2.patch" @@ -53,7 +56,7 @@ ], "catalogs": { "bun": { - "@types/bun": "1.4.2" + "@types/bun": "1.4.3" }, "copilot": { "@github/copilot": "1.0.80", diff --git a/scripts/conversation-plan-worker.ts b/scripts/conversation-plan-worker.ts index d8b19f3fd..720741260 100644 --- a/scripts/conversation-plan-worker.ts +++ b/scripts/conversation-plan-worker.ts @@ -309,8 +309,8 @@ async function namespace(report: Record): Promise { }); socket.once("error", (error: NodeJS.ErrnoException) => { clearTimeout(timer); - // Bun 1.4.2 maps kernel ENETUNREACH to ECONNREFUSED in this verified route-free namespace. - let mapped = Bun.version === "1.4.2" && error.code === "ECONNREFUSED"; + // Bun 1.4.4 maps kernel ENETUNREACH to ECONNREFUSED in this verified route-free namespace. + let mapped = Bun.version === "1.4.4" && error.code === "ECONNREFUSED"; if (mapped || ["ENETUNREACH", "EHOSTUNREACH", "EACCES", "EPERM"].includes(error.code ?? "")) { report.socketDenial = mapped ? "bun-mapped-unreachable" : "routing-denial"; resolve();