Skip to content

build: pin Bun 1.4.2 across mise, CI, release and runtime images - #108

Merged
roodboi merged 7 commits into
nextfrom
claude/hack-1211-bun-1-4-2
Oct 1, 2026
Merged

roodboi merged 7 commits into
nextfrom
claude/hack-1211-bun-1-4-2

Conversation

@roodboi

@roodboi roodboi commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Current integration status — 2026-10-01

PR #112 is merged into next at f00a6478, including the acceptance stand-in fix; duplicate #116 is superseded. The pin branch includes that exact next history at head e80171be without rewriting its qualified commits. Its source tree is byte-identical to a459762a (5a4150bd); the current diff against next is only the 11 Bun-pin files. All eight fresh exact-head CI jobs pass (run 36896025750).

Native upgrade and rollback qualification passed on the M3. The signed candidate at e582353d combines #122's recovery source a330a73a with this unchanged pin. Both versions use the same recovery source; the only difference is the 11 Bun-pin files. The actual compiled CLI revisions were 1.3.9 → 1.4.2 → 1.3.9. All six new bundle manifest entries verified. At both restore points, Event Agent reported 14 services and nine healthy services; a uniquely owned Redis-volume marker survived and was removed after rollback. Verified native HTTPS health/sign-in and all 17 sign-in assets returned 200, and Chrome rendered the sign-in route after upgrade and again after rollback. Frontend and runtime owner paths/hashes matched each selected bundle; wrong-runtime selections were rejected without changing owner configuration. CA bytes/inode, VM birth/disk identities, sibling receipt and all four volume names remained unchanged.

Normal Bun 1.4.2 down exited zero, retired the owned lifecycle and native frontend, released dependency/HTTPS listeners, and retained four volumes. An earlier baseline stop used a different tmux server with a same-named foreign session and correctly refused host lifecycle cleanup after native cleanup; the matching app-server context resolved that harness selection error. No foreign session or runtime state was manually removed.

Compatibility review, signed build, retained-app upgrade/rollback and exact-head CI gates are complete. This qualification does not establish a crash fix, performance improvement, normal port-443 OAuth/search/image acceptance, or release readiness. Those remain separate work; no release publication is requested. The squash message must describe a compatibility-qualified upgrade and retain the unproven crash-cause/effect caveat.

The sections below preserve historical qualification and review context. Their old branch/dependency/gate status is superseded by this section.


Summary

Moves the repository's Bun toolchain from 1.3.9 to 1.4.2, managed through mise.

Why: Bun 1.3.9 intermittently crashes (panic(main thread): Segmentation fault, "Bun has crashed") while running tests/native-https-owner.test.ts on the macOS test job. Occurrences:

Only one of those crashes has a decoded trace. It ends in usockets us_internal_dispatch_ready_poll.

Bun 1.4.0 includes upstream changes to usockets peer-reset and poll-error handling (oven-sh/bun#39600, #39621, #39860). None is shown to fix this segfault, and its cause remains unproven.

This pin is a compatibility-qualified toolchain upgrade, not a proven crash fix. The hosted crashes may or may not stop on 1.4.2, and any crash on 1.4.2 should be recorded per run. The bounded local loop did not reproduce the crash on 1.3.9 either (see below).

Commit message caveat: the pin commit a459762a says "Bun 1.4 carries upstream fixes to that usockets dispatch path". Its content copies (c1e4f568, and root's c906cb5c) say the same. That sentence overstates the evidence. Those commits are left unrewritten so that their exact qualified SHAs stay valid. The squash commit message should use the wording above instead.

Every pin moves together:

  • mise.toml, .tool-versions, package.json packageManager;
  • .github/workflows/ci.yml (5 jobs), release.yml (3), release-prepare.yml, release-node-runtime-image.yml;
  • docker/node-runtime/Dockerfile and docker/slim-runtime/Dockerfile (oven/bun:1.4.2);
  • scripts/build-native-candidate.sh's version check and docs/guides/native-candidate.md.

Unchanged on purpose:

  • bun.lock: a frozen install succeeds without changing it.
  • The consumer Compose example in docs/cli.md and a test fixture's image string, which are not repository pins.
  • The toolchain comments that explain a workaround observed on 1.3.9.

Release note: release binaries and the node/slim runtime images will be built with Bun 1.4.2 from the next release on. Release qualification stays with the release workflow.

Verification

  • mise install bun@1.4.2, then bun --version reports 1.4.2.
  • bun install --frozen-lockfile: lockfile unchanged.
  • At a459762a on 1.4.2, uncached (TURBO_FORCE=1, 0 cached): bun run typecheck and bun run check pass.
  • bun run privacy:check at a459762a: ok.
  • Full TypeScript suite on 1.4.2, locally at a459762a (this head, the pin on top of fix: keep a published Unix socket's identity through startup failure #112): 1,774 tests across 250 files, 1,707 pass, 67 skip, 0 fail, no Bun crash markers, and no new host crash reports during the run. Run sequentially, with the host otherwise idle.
  • No 1.3.9 pin remains in workflows, Dockerfiles, mise.toml, .tool-versions or packageManager. The remaining mentions are the intentional ones listed above, one AF_UNIX test comment about 1.3.9 behavior, and an unrelated fixture version string.

CI at exact head a459762a (run 36758349825, pull_request, attempt 1)

All 8 checks pass:

  • test, docker-e2e, Runtime state models, linux-process-lifetime, runtime-images, secret-scan;

  • Candidate core on macOS and on Ubuntu.

  • Bun actually used: every Bun job installed 1.4.2+744846f84 (bun --revision). The runtime images build from oven/bun:1.4.2. The @types/bun@1.3.5 in install logs is the type package, not the runtime.

  • test (blacksmith macOS 15): 1,774 tests across 250 files, 1,676 pass, 98 skip, 0 fail (102.7 s).

    • dist/hack was compiled by 1.4.2 (bun build index.ts --compile).
    • No "Bun has crashed", panic or segfault markers in any job log.
  • Candidate core jobs install only Zig through mise. They exercise the Rust candidate, not Bun.

  • Local and CI skip counts differ (67 vs 98) because of live-gated tests that depend on the environment.

Limit: one green CI run cannot show that a crash of about 3% frequency is gone. HACK-1211 defines a bounded reproduction and comparison experiment for that. It has not been dispatched.

Refs HACK-1211.

Integration review against the current candidate (codex/event-agent-https-acceptance at 2fe54aa9, read-only)

  • No merge conflict: the candidate touches none of this PR's 11 files. The pin alone (83571a61..a459762a) applies to 2fe54aa9 with a clean merge (git merge-tree). The candidate's copies of the fix: keep a published Unix socket's identity through startup failure #112 files are identical to 83571a61.
  • No Bun 1.4-sensitive code added: the candidate's TypeScript beyond fix: keep a published Unix socket's identity through startup failure #112 (native-project review, start, restore, restart preflight, retained images) adds none of the following:
    • process.env set to undefined;
    • direct Unix-socket listens or net servers;
    • Bun version gates or compile-flag changes.
      Its other changes are Rust (packages/runtime-core), models and a Python acceptance test, none of which run on Bun.
  • Concern 1, native runtime change: scripts/build-native-candidate.sh refuses any Bun other than exactly 1.4.2 (exit 69).
    • If this pin enters the active acceptance stack, the M3 native candidate must be rebuilt with Bun 1.4.2 via mise.
    • Evidence from a candidate compiled with 1.3.9 would not carry over to it.
    • That script has not yet run on 1.4.2 anywhere: CI does not run it and it was not run locally.
    • Recommendation: keep the pin out of the in-flight acceptance run, land it separately, then rebuild and requalify the native candidate once on 1.4.2.
  • Concern 2, candidate tests unrun on 1.4.2: the candidate's changed TypeScript tests (5 native-project test files plus the owner and socket tests) have run on 1.3.9 only. The combined tree has not been tested on 1.4.2. This was not run here to avoid competing with the M3 run.
  • Minor:
    • The .hack toolchain container takes Bun from mise.toml, so it follows this pin on rebuild. Its build task and the 1.3.9 cross-device staging workaround comments (.hack/toolchain/run.sh, .hack/README.md) are unexercised on 1.4.2; keeping the workaround is harmless.
    • @types/bun is latest (resolved 1.3.5) and lags the runtime; typecheck passes.

Combined-tree qualification with #120 (local, Bun 1.4.2)

Source:

Gates (all exit 0):

  • bun install --frozen-lockfile: no tracked changes.
  • TURBO_FORCE=1, 0 cached: typecheck and check (which includes privacy:check) pass.
  • test, 0 cached: 1,804 tests across 251 files, 1,737 pass, 67 skip, 0 fail, 7,936 expect() calls (127.8 s), no crash markers. The pass count equals fix(native): align stopped recovery preflight with retained startup #120's local 1.3.9 gate (1,737).

Compiled CLI: bun run build bundled 588 modules into dist/hack, which embeds runtime 1.4.2 (BUN_BE_BUN=1). The smoke used an isolated HACK_HOME and HOME, with no Docker, daemon, native runtime, ports or routing. It passed 12 of 12 checks:

  • --version (hack v4.2.1), --help, help --all;
  • projects --json (valid JSON);
  • a global-config round trip;
  • the scripted e2e subset on the compiled binary, 7 of 7 pass with 0 skip: automation-check, init, env-secrets, worktree-secrets, worktree-registry, worktree-branch-default, domain-migration-files ("no runtime invoked").

The first smoke run had one FAIL: my check expected a bare 4.2.1. I corrected it and reran the whole smoke. The doctor, agent-docs-sync, tmux-session and Docker tiers were not run.

Crash-path regression. The hosted crash site is tests/native-https-owner.test.ts. #120's run 36776561885, attempt 1, shows Bun 1.3.9 panic(main thread): Segmentation fault at address 0x80, exit 133, about 11.6 s into a full bun test process; attempt 2 passed. The loop ran that file 50 times per version (50 of 50 iterations attempted, 274 s), alternating a Bun 1.3.9 control:

Bun runs exit 0 tests per run crashes hangs other
1.4.2 50 50 13 pass, 0 skip, 0 fail (3,006 expects in total) 0 0 none
1.3.9 control 50 49 13 pass, 0 skip, 0 fail on each clean run 0 0 one SIGKILL (below)

The SIGKILL was in iteration 32: the run exited 137 about 2 s in, after printing only its header.

  • There was no Bun crash banner, no diagnostic report, and no kernel kill, memory-pressure or code-signing entry.
  • It is unattributed and is not the hosted crash signature.
  • My loop's classifier first counted it as a timeout; that was corrected.

Interpretation:

  • This local loop did not reproduce the hosted crash on 1.3.9 (0 of 50 crash banners), so 0 of 50 on 1.4.2 is not evidence that the crash is gone. It shows no regression in this path under 1.4.2.
  • The hosted crashes happened inside a full-suite process, which isolated-file runs may not recreate.
  • One host crash report fell in the qualification window: tool (SIGKILL, code signature invalid), whose parent is a hack_runtime_core test binary from another session. No Cargo ran here.

Not run:

  • the native candidate build and any native, VM, Docker e2e or benchmark run (excluded by scope);
  • hosted CI on the combined tree: branch pushes do not trigger CI in this repository (no push runs for branches), and no cumulative PR was opened, so there is none.

Carry-over to #121 (4a9ac29dc24a98b235ac380f6f3cd3077069c80f): #121 adds one commit over f88c4227, touching only Rust and the README in packages/runtime-core. The pin applies to it cleanly (merge-tree tree 50c54c3b). Everything Bun executes is byte-identical to the tested c1e4f568, so this qualification covers #121 plus the pin. It is branch qualification only; it is not native or browser acceptance.

Dependency and status (draft until results are reviewed)

Stacked on hack-dance/hack#112 at 83571a61 (startup ownership fixes; all required checks pass there). Until #112 lands, this PR's diff includes #112's commits. Review only the top commit, a459762a (the pin). After #112 lands, this branch is rebased onto next so that only the pin remains. It is the same patch as the earlier a52dcec9 and fb44c730, with only hunk offsets in ci.yml moved.

History: the first CI run at fe78bd53 (pin only) failed test with 51 of 1,760 tests and no Bun crash. Two Bun behavior changes caused it, both fixed by hack-dance/hack#109 (merged, 98c2694b):

  1. From 1.3.14, a Unix-socket server's close unlinks its bound path by name. fix: publish Unix socket endpoints by link so a runtime close never removes a replacement #109 publishes the MCP, HTTPS owner and owner-challenge endpoints by link(2) from a staging name. fix: keep a published Unix socket's identity through startup failure #112 then closes the startup ownership windows that review found.
  2. On 1.4, assigning undefined to a process.env key stores "undefined". fix: publish Unix socket endpoints by link so a runtime close never removes a replacement #109 deletes such variables in tests.

Gate (explicit):

@linear-code

linear-code Bot commented Sep 30, 2026

Copy link
Copy Markdown

HACK-1211

@roodboi
roodboi marked this pull request as draft September 30, 2026 13:29
@roodboi
roodboi force-pushed the claude/hack-1211-bun-1-4-2 branch from fe78bd5 to fb44c73 Compare September 30, 2026 13:48
@roodboi
roodboi marked this pull request as ready for review September 30, 2026 15:33
roodboi added a commit that referenced this pull request Sep 30, 2026
…emoves a replacement (#109)

## Summary

Compatibility prerequisites for moving past Bun 1.3.9
([#108](#108),
HACK-1211). Both changes are correct on 1.3.9 as well, so this PR is
safe to merge on its own; #108 stacks on it.

### 1. Unix-socket endpoints can no longer be removed by a runtime close
(product)

From Bun 1.3.14, closing a `node:net` Unix-socket server unlinks its
bound path **by name**, whatever that path holds by then. Bun also
replaces an existing file at the bound path on `listen`. A standalone
probe keeps a replacement file on 1.3.9 and loses it on 1.3.14 and
1.4.2.

Three servers bound their public endpoint directly, so a close could
remove a foreign replacement that their identity-checked cleanup exists
to preserve:
- `src/mcp/socket-backend.ts`: `mcp.sock`. Its test `idle cleanup
preserves replacement endpoint and claim identities` failed on 1.4.2.
- `src/backends/native-https-owner-server.ts`: `control.sock`. Its
pre-close path check narrowed the window but did not close it, and
`retire()` closed without a fresh check.
- `src/backends/native-project-https.ts`: the owner challenge
`owner.sock`. `stopOwnerChallenge` closed first and checked identity
afterward.

**Fix:** the new `listenPublishedUnixSocket`
(`src/lib/unix-socket-publish.ts`), the smallest supported change:
1. Bind a fresh staging name in the same private directory, never longer
than the endpoint's own name so existing path-length budgets hold, under
an owner-only umask.
2. Verify it is this user's socket.
3. Publish it with `link(2)`. This refuses an existing endpoint
(`EEXIST`, surfaced as `UnixSocketEndpointExists`) instead of replacing
it.
4. Verify the published inode, then remove the staging name.

A runtime close-time unlink then finds nothing, and each endpoint is
removed only by its caller's existing identity-checked cleanup. On any
failure after listening, the helper closes the server, removes the
staging name, and removes the endpoint only while it still holds this
socket.

**Public endpoint contract: unchanged.** The same path, a socket inode,
mode `0600`, and the same recorded device/inode (MCP receipt, owner
`endpoint.json`); clients connect exactly as before.

**Residual:** a hidden staging name exists in the private directory only
between `listen` and publication. A crash inside that window could leave
one such file behind. It is never bound again and blocks nothing.

Per-caller changes are minimal:
- **MCP:** keeps its pre-check and maps a publication collision to its
existing "already exists" error.
- **HTTPS owner:** keeps its identity checks around `chmod`.
- **Owner challenge:** records the published identity immediately, so a
failure after publication (for example the injected `chmod` failure)
removes its own endpoint by identity instead of leaving it behind.

### 2. Tests delete unset environment variables (test-only)

Bun 1.4, like Node, stores the string `"undefined"` when a `process.env`
key is assigned `undefined`. Tests that unset that way, or restored a
captured value that was never set, left `"undefined"` behind, and it
leaked into later files in the same `bun test` process. That caused most
of #108's 51 failures.
- 49 literal unsets now use `Reflect.deleteProperty`.
- 63 restores of captured values use a shared `tests/helpers/env.ts`
`restoreEnv`, which deletes a missing value.
- `config-paths.test.ts`'s local helper is fixed the same way.
- No product code assigns `undefined` to `process.env`.

## Verification

- **New `tests/unix-socket-publish.test.ts`**, 6 controls, passing on
**Bun 1.3.9 and 1.4.2**:
- the published endpoint serves clients, survives close, and is removed
only by identity; the staging name stays in the same directory, is no
longer than the endpoint name, and is gone after publication;
  - a replacement survives normal and forced close;
  - an existing endpoint refuses startup and is never replaced;
- of two concurrent owners, exactly one publishes and the other leaves
it intact;
  - a restart after owned cleanup publishes a fresh endpoint;
  - a startup that cannot bind creates nothing.
- **Mutation check** on both versions: leaving the staging name,
publishing with clobbering `rename`, and binding the endpoint directly
(the previous design) each make controls fail. The previous design loses
the replacement on 1.4.2, and replaces an existing endpoint at `listen`
even on 1.3.9.
- **Server test files on 1.3.9 and 1.4.2:** `mcp-socket-backend` 12/12,
`native-https-owner` 12/12, `native-project-https` 24/24.
- **All 49 affected test files in one `bun test` process** (mirroring
CI's shared environment): 410/410 on 1.4.2 and 410/410 on 1.3.9.
- Typecheck and `bun run check` pass uncached; the 47 changed test files
pass `ultracite check`; privacy ok.

Refs HACK-1211.

<!-- codesmith:footer -->
---
<a
href="https://app.blacksmith.sh/hack-dance/codesmith/hack/pr/109?autoLogin=true&ref=codesmith_pr_footer"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img
alt="View with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a>
<a
href="https://backend.blacksmith.sh/track/enable-autofix?expires=1793368061&installation_model_id=17053&pr_number=109&ref=codesmith_pr_footer&repository=hack-dance%2Fhack&return_to=https%3A%2F%2Fgithub.com%2Fhack-dance%2Fhack%2Fpull%2F109&signature=48ce6d15d860f958f4b6fe36d7376c8e5c2b2f2c1b8f633f2a03e9879b997622"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img
alt="Autofix with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a>
<sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you
need. Autofix is disabled.</sup>

<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->

---------

Co-authored-by: hack-cli-tests <tests@hack>
@roodboi
roodboi force-pushed the claude/hack-1211-bun-1-4-2 branch from fb44c73 to a52dcec Compare September 30, 2026 15:52
@roodboi
roodboi marked this pull request as draft September 30, 2026 15:54
hack-cli-tests added 6 commits September 30, 2026 12:39
A review of #109 found two startup ownership gaps.

The native HTTPS owner discarded the identity listenPublishedUnixSocket
returned and only recorded one after lstat, chmod and lstat of the path.
A failure after publication then skipped listener and endpoint cleanup,
and a replacement in that window could be chmodded or recorded as the
endpoint. The owner now keeps the published identity at once, compares
its first observation against it, and never changes the endpoint by path.
Failure cleanup always closes the listener, which can no longer unlink
anything but the retired staging name, and then removes the endpoint only
while it is this listener's inode; a replacement is kept.

The helper awaited listen() outside its cleanup, so a listen that bound
the staging name and then failed could leak that socket and listener.
Listening is now inside the cleanup, and a failed start removes only a
staging socket this user created. The helper also sets the endpoint mode
(0600) on the staging inode before publication, so the MCP backend, the
HTTPS owner and the owner challenge no longer chmod the public path.

Controls: bind-then-fail, mode-preparation failure, an endpoint at the
AF_UNIX path limit (and one byte over: refused cleanly on Bun 1.3.9,
bound in full on 1.4.2, never truncated), and an owner fault or
replacement between publication and first observation, on Bun 1.3.9 and
1.4.2.
The private-bind fixture hooked chmod on the public mcp.sock to prove the
socket is private before its mode is set and that the creation mask is
restored. Since the endpoint's mode is now set on its staging socket
before publication, the hook never fired and the check failed. It now
observes that staging chmod with the same privacy and mask checks,
requires mode 0600, and fails if the published endpoint is ever chmodded
by path.
Stand-in invocations ran concurrently (a foreground `up` while the driver
polls `ps`) and each did an unlocked read-modify-write of state.json. A
`ps` that loaded the state before the second `up` saved its foreground
token then saved its stale copy over it, so `up` saw its token gone and
exited 0 before readiness; lost call records failed the acceptance test
as well. That failed 26 of 40 local runs, and Runtime state models on CI.

Each invocation now holds an exclusive flock across its read-modify-write
and releases it only before its long waits (the foreground loop and the
ps-hang fault). 40 of 40 local runs pass.
…a socket

A second review of the Unix-socket publication found three staging-path
windows where an entry this attempt could not prove was its own could be
changed or removed:

- After an ambiguous partial bind (no recorded identity), cleanup
  unlinked any same-uid socket at the staging name.
- The mode was set by path after an awaited lstat, so a replacement in
  that gap could be chmodded before the postcheck refused it.
- On success the staging name was unlinked unconditionally after the
  awaited link and endpoint lstat.

The socket is now created with exactly its mode (the umask during the
synchronous bind), so nothing is ever chmodded, and its identity is
recorded in the same tick. Publication links only while the staging name
is still that socket, and retirement removes it only while it is (check
and removal back to back). An entry that is not this socket, or cannot be
proven to be, is never removed: on failure it is moved aside while the
server closes, so the runtime's close-time unlink by name cannot reach
it, and then put back with the same inode.

The owner challenge's chmod dependency becomes an afterOwnerSocketPublish
test seam, and the private-bind fixture now requires the socket to be
created private with mode 0600 and no socket name to be chmodded.
…ng entry

The failure close moved an unproven staging entry to one random holding
name: if that name was occupied the close went ahead unprotected, and a
holding entry created between the check and the rename was overwritten.
The entry is now moved with link(2), which never replaces a holding
entry, over a bounded list of fresh holding names, and the staging name
is dropped only while it is still the linked entry. An entry that cannot
be moved aside (every holding name occupied, or not hard-linkable) leaves
the close to proceed, now documented as a residual.

The helper's documentation now states its scope: accidental and
concurrent entries in a private directory, not an adversarial process of
the same user, with the remaining path-based and post-return residuals.
Bun 1.3.9 intermittently segfaulted inside its own socket poll dispatch
while running tests/native-https-owner.test.ts on the macOS test job (2 of
60 recent test jobs, HACK-1211). Bun 1.4 carries upstream fixes to that
usockets dispatch path.

Every repository pin moves together: mise.toml, .tool-versions,
packageManager, the CI and release workflows, the node and slim runtime
images, and the native candidate build's version check. The lockfile is
unchanged; a frozen install succeeds.
@roodboi
roodboi force-pushed the claude/hack-1211-bun-1-4-2 branch from a52dcec to a459762 Compare September 30, 2026 18:24
@roodboi
roodboi marked this pull request as ready for review October 1, 2026 17:33
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-01T17:34:33.346091Z e80171b Draft marked ready
🔒 Security Review ✅ Completed 2026-10-01T17:36:47.643535Z e80171b Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@roodboi
roodboi merged commit aa2ae7e into next Oct 1, 2026
10 checks passed
@roodboi
roodboi deleted the claude/hack-1211-bun-1-4-2 branch October 1, 2026 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant