Prototype LLRT native executor and package#14
Merged
Conversation
Rationale: Explore LLRT as the preferred lightweight execution runtime by adding a standalone TypeScript-friendly @robinbraemer/llrt package, napi-rs native bridge, codemode executor adapter, native packaging workflow, and benchmark/stress evidence. Rejected: Do not replace the fallback executors yet; LLRT still needs a real GitHub Actions native matrix run and artifact inspection before production-default adoption. Do not embed LLRT directly into codemode; the standalone package keeps native packaging and runtime API reusable. Risk: Introduces a new Rust/native package and release workflow. The prototype is intentionally JSON-safe and fresh-VM-per-call, which is safer but may leave reusable-VM performance for later. Tested: mise exec -- task ci; mise exec actionlint -- actionlint .github/workflows/*.yml; mise exec -- pnpm --filter @robinbraemer/llrt run verify:native-artifacts; mise exec -- npm pack --dry-run from packages/llrt; benchmark:executors report generation. Not-tested: Real GitHub Actions native matrix run across macOS and Linux runners; publishing to npm; CNAP repository consumption of the published package.
Rationale: Clean CI failed because codemode typechecked and tested against the LLRT workspace package before its dist entry existed, and the native packaging workflow installed the whole workspace, pulling in codemode's isolated-vm dependency on macOS x64. Build LLRT before recursive typecheck, scope native packaging installs to the LLRT workspace, and run native-only LLRT suites only when a native binding is available or after the native matrix builds one. Rejected: A root tsconfig path alias to LLRT source broke codemode's rootDir boundary. A full duplicated LLRT declaration in codemode would reduce build coupling but created a larger drift surface, so the peer declaration is limited to the runtime shape codemode consumes. Building LLRT native in regular CI was also rejected because the existing native matrix is the right owner for platform-specific native execution coverage. Risk: The lint task now does one small LLRT tsup build before typecheck. Regular CI skips native-only LLRT runtime coverage when no binary exists, but the native matrix now forces that suite after each platform build with LLRT_REQUIRE_NATIVE_TESTS=1. The codemode optional-peer declaration can drift if the LLRT runtime call shape changes, but it is intentionally narrow and CI still builds/tests against the real workspace package. Tested: rm -rf packages/llrt/dist && mise exec -- pnpm --filter @robinbraemer/codemode run typecheck Tested: mise exec -- pnpm --filter @robinbraemer/llrt exec vitest run test/native-loader.test.ts test/native-prebuild-workflow.test.ts Tested: mise exec -- pnpm --filter @robinbraemer/codemode exec vitest run test/llrt-native-executor.test.ts Tested: no-native simulation: temporarily move packages/llrt/*.node and packages/llrt/native/*.node, then mise exec -- task ci Tested: mise exec -- go run github.com/rhysd/actionlint/cmd/actionlint@latest .github/workflows/*.yml Tested: mise exec -- task ci
f10087a to
d0120d1
Compare
Rationale: The LLRT executor PR now has green native builds, but the new packages still used placeholder 0.0.0 versions and codemode declared an unusable exact LLRT peer. This prepares the first publishable LLRT package and the codemode release that can consume it. Rejected: Keeping the peer dependency tied to the local workspace version was avoided because codemode should encode the LLRT API floor instead of forcing every compatible LLRT patch release as the new minimum. Risk: Consumers must install @robinbraemer/llrt ^0.1.0 when they opt into the LLRT executor; the package remains an optional peer from codemode's perspective. Tested: mise exec -- pnpm --filter @robinbraemer/llrt exec vitest run test/package-publication.test.ts test/native-artifact-verifier.test.ts Tested: mise exec -- pnpm --filter @robinbraemer/codemode exec vitest run test/package-publication.test.ts Tested: mise exec -- pnpm --filter @robinbraemer/llrt run verify:native-artifacts Tested: mise exec -- task ci
Rationale: npm trusted publishing performs its OIDC token exchange through npm publish, so release jobs should publish from package directories with the npm CLI instead of pnpm publish. Rejected: Keeping --no-git-checks was avoided because npm treats it as an unknown git-checks config and warns that this will stop working in a future major version. Risk: Release publishing behavior changes only at the final npm publish steps; build, pack, native artifact, and smoke checks stay unchanged before publish. Tested: mise exec -- pnpm --filter @robinbraemer/llrt exec vitest run test/native-prebuild-workflow.test.ts Tested: mise exec -- pnpm --filter @robinbraemer/codemode exec vitest run test/package-publication.test.ts Tested: mise exec -- go run github.com/rhysd/actionlint/cmd/actionlint@latest .github/workflows/*.yml Tested: mise exec -- task ci
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR prototypes an LLRT-first execution path for codemode and prepares a standalone TypeScript-friendly
@robinbraemer/llrtpackage.It includes:
packages/llrtpackage with a napi-rs Rust binding around LLRT's Rust VM API.LlrtRuntime.callJson<TInput, TOutput>()API with typed success/failure results, memory/wall-time/stack options, host callbacks, fresh VM per call, and tests for errors, isolation, callbacks, memory, timeout, and stress behavior.LlrtNativeExecutor,createExecutor()preference for LLRT when installed, and fallback executors left in place.llrt-native,isolated-vm, and QuickJS WASM.internal/superpowers/.@robinbraemer/llrt@0.1.0and@robinbraemer/codemode@0.3.0.Verification
Local verification:
mise exec -- task cimise exec -- pnpm --filter @robinbraemer/llrt exec vitest run test/package-publication.test.ts test/native-artifact-verifier.test.tsmise exec -- pnpm --filter @robinbraemer/codemode exec vitest run test/package-publication.test.tsmise exec -- pnpm --filter @robinbraemer/llrt run verify:native-artifactsmise exec -- pnpm --filter @robinbraemer/llrt run smoke:packed-installmise exec -- pnpm --filter @robinbraemer/codemode run benchmark:executors -- --report internal/superpowers/reports/2026-06-10-llrt-executor-benchmark.md --json internal/superpowers/reports/2026-06-10-llrt-executor-benchmark.jsonmise exec -- go run github.com/rhysd/actionlint/cmd/actionlint@latest .github/workflows/*.ymlGitHub verification on head
e74ef1f:Current verdict
LLRT is now a strong default candidate for codemode. This PR proves the practical package boundary: importable TypeScript API, napi-rs bridge, fresh VM isolation, JSON-safe host callbacks, resource controls, codemode executor compatibility, reproducible native artifacts across the target runner matrix, and packed-install smoke coverage.
The production adoption still needs a separate CNAP-side package consumption change after this package is merged/released. Keep fallback engine selection available for emergency rollback while LLRT becomes the preferred/default executor.
Handoff prompt for the next AI agent
You are continuing the LLRT-first runtime adoption work after this
cnap-tech/codemodePR. Preserve the current direction unless evidence contradicts it: standalone@robinbraemer/llrtpackage first, codemode consumes it through a thin adapter, fallback engines remain available for rollback.Completed in this PR:
packages/llrtexists as a standalone Node/TypeScript package backed by a Rust napi-rs addon.LlrtRuntime.callJson<TInput, TOutput>()with typedLlrtResult<TOutput>.memoryMB,wallTimeMs,cpuTimeMsplaceholder, andmaxStackBytes.TIMEOUT,MEMORY_LIMIT,SERIALIZATION_ERROR,EVALUATION_ERROR,NATIVE_LOAD_ERROR, andRUNTIME_DISPOSED.LlrtNativeExecutor;createExecutor()prefers LLRT when@robinbraemer/llrtis installed, falls back only when the LLRT package itself is missing, and fails loudly when installed LLRT is broken.isolated-vm, QuickJS WASM, andLlrtProcessExecutorremain available.packages/llrt/npm/*for darwin/linux arm64/x64..github/workflows/llrt-native.ymlbuilds and packages all native artifacts.verify:native-artifactsvalidates optional native package manifests; strict mode also requires.nodefiles after artifacts are downloaded.smoke:packed-installpacks main + current native package and tests import/execution from a temporary consumer project.packages/codemode/scripts/benchmark-executors.ts, with a saved report atinternal/superpowers/reports/2026-06-10-llrt-executor-benchmark.md.internal/superpowers/specs/2026-06-10-standalone-llrt-typescript-runtime-design.mdandinternal/superpowers/plans/2026-06-10-standalone-llrt-calljson.md.Recommended next steps:
@robinbraemer/llrt@0.1.0plus@robinbraemer/codemode@0.3.0using the repository's release process.@robinbraemer/llrtso the optional peer is present in production.Important local caveats:
mise exec -- ...for codemode verification so Node stays at the pinned Node 24 ABI. Running rawtask ciunder Node 26 can fail becauseisolated-vmwas built for Node 24..codex/is unrelated and should not be committed.dist/,node_modules/,packages/llrt/vendor/,packages/llrt/native/target/,*.node, and*.tgzare intentionally ignored.