Skip to content

fix(release): resolve the embedded package runtime from process.execPath - #44

Merged
robinbraemer merged 2 commits into
mainfrom
fix/embedded-package-runtime-loading
Aug 17, 2026
Merged

fix(release): resolve the embedded package runtime from process.execPath#44
robinbraemer merged 2 commits into
mainfrom
fix/embedded-package-runtime-loading

Conversation

@robinbraemer

Copy link
Copy Markdown
Member

v0.10.0's released binaries fail every akua pkg command with AKUA_PACKAGE_UNAVAILABLE. Found by actually installing v0.10.0 via Homebrew and running the real binary — the existing install-smoke test stubs the executable with a fake shell script and never proves the packaged runtime loads.

Two compounding bugs, both fixed:

  1. stagePackageRuntime never staged @akua-dev/sdk itself — only native/native-engines. Its package.json declares files: ["dist", ...] (a directory), unlike the flat lists native/native-engines use, so this needed directory-listed manifest entries expanded into individual files before staging (copyFileSync can't copy a directory).
  2. Even staged correctly, bun build --compile couldn't load it at runtime. Without --external, the bundler tries to inline @akua-dev/sdk/execute, which transitively needs @akua-dev/native's platform .node binding — a real binary it can't inline. Marking @akua-dev/* --external keeps it a real runtime import, but a compiled executable resolves bare specifiers against its own embedded virtual filesystem ($bunfs), never the real one — so it still can't see the sidecar node_modules staged next to it on disk. process.execPath resolves to the executable's real filesystem location even when compiled (empirically confirmed); resolvePackageExecute in services-live.ts now imports the SDK from an absolute path built off it, falling back to normal package resolution when the sidecar isn't present (dev/test/build).

This is the one place in the CLI that needs a dynamic import — a compiled sidecar-native-module architecture cannot resolve its runtime dependency through a static specifier the bundler would either inline (breaking the native binding) or resolve against its own virtual filesystem. Cached via Effect.cached, not a mutable variable — no native Promise types in production code.

Verified end to end for real (not mocked): bun scripts/release.ts package built a real archive, extracted to a clean directory outside the repo, and the extracted akua binary's pkg version/--help/init/render all worked against the real staged node_modules. Reproduced the exact AKUA_PACKAGE_UNAVAILABLE failure from the real Homebrew-installed v0.10.0 binary before this fix.

Gates: bun test (165 pass), bun run build, bun run generate:check.

v0.10.0's released binaries fail every akua pkg command with
AKUA_PACKAGE_UNAVAILABLE. Two compounding bugs, both found and fixed
by actually installing v0.10.0 via Homebrew and running the real
extracted binary (not the mocked install-smoke test, which stubs the
executable and never proves the packaged runtime loads):

1. stagePackageRuntime only staged native/native-engines; @akua-dev/sdk
   itself was never copied into the archive's node_modules. Its
   package.json declares files: ["dist", ...] (a directory), unlike
   native/native-engines' flat file lists, so a naive fix needed
   directory-listed manifest entries expanded into their individual
   files (expandPackageManifestFiles/walkPackageDirectory) before
   staging — copyFileSync can't copy a directory.
2. Even with sdk staged correctly, bun build --compile still couldn't
   load it at runtime: without --external, the bundler tries to inline
   @akua-dev/sdk/execute, which transitively needs @akua-dev/native's
   platform .node binding — a real binary the bundler cannot inline.
   Marking @akua-dev/* --external keeps it a real runtime import, but a
   compiled executable resolves bare specifiers against its own
   embedded virtual filesystem (), never the real one, so it
   still couldn't see the sidecar node_modules staged next to it on
   disk. process.execPath resolves to the executable's real filesystem
   location even when compiled (empirically confirmed), so
   resolvePackageExecute in services-live.ts imports the sdk from an
   absolute path built off it, falling back to normal package
   resolution when the sidecar isn't present (dev/test/build).

Rationale: this is the one place in the CLI that needs a dynamic
import — a compiled sidecar-native-module architecture cannot resolve
its runtime dependency through a static specifier the bundler would
either inline (breaking the native binding) or resolve against its own
virtual filesystem. The result is cached via Effect.cached, not a
mutable variable.
Rejected: leaving @akua-dev/sdk bundled inline — impossible, it
transitively needs a real .node file. Leaving it a static external
import — resolves against , not the real sidecar path.
Tested: bun test (165 pass); bun run build; bun run generate:check;
real end-to-end proof — bun scripts/release.ts package built a real
v0.10.1-local archive, extracted to a clean directory outside the repo,
and the extracted akua binary's pkg version/--help/init/render all
worked against the real staged node_modules (previously reproduced the
exact AKUA_PACKAGE_UNAVAILABLE failure from the real Homebrew-installed
v0.10.0 binary before this fix).
Rationale: every other release-matrix leg (darwin-arm64, darwin-x64,
linux-arm64, windows-x64) already runs install-smoke on a GitHub-hosted
runner; linux-x64 was the sole exception, pinned to the self-hosted
akua-x64-ci-v2 pool. That pool's shared egress IP has been getting
codeload.github.com 429-rate-limited under concurrent CI load across
akua-dev repos, failing this exact job 3 times in a row on PR #44 while
every sibling leg passed cleanly. The smoke step only needs a generic
Linux x64 environment to extract and run an already-built artifact, so
there's no correctness reason to keep it on the flaky self-hosted pool.

Tested: bun test test/release.test.ts (23 pass)
@robinbraemer
robinbraemer merged commit c827efe into main Aug 17, 2026
10 of 16 checks passed
@robinbraemer
robinbraemer deleted the fix/embedded-package-runtime-loading branch August 17, 2026 17:00
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