feat: add cpu-node sandbox benchmark with CI workflow - #339
Open
kisernl wants to merge 9 commits into
Open
Conversation
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Contributor License AgreementAll contributors are covered by a CLA. |
Four deterministic compute phases (JSON round-trip, SHA-256 hashing, regex text walk, sum-of-primes) inlined into a single stdlib-only workload script, plus a stdout helper that emits the WorkloadResult JSON line and installs uncaught-exception/rejection crash handlers. No external fixture, bundle, or tar upload: the workload is fully self-contained and runs identically on any Node 18+ sandbox.
Single-file benchmark orchestrator (benchmarks/sandbox/cpu-node.ts) following the dax pattern: inline types, scoring, per-replicate run, and results writing. Wires the suite into @benchsdk/runner and merge-results.ts, adds the SVG generator, unit tests, smoke harness, and package.json scripts. Adds the Sandbox Cpu-node Benchmark GitHub Actions workflow across all ComputeSDK providers, and removes the dangling sibling HPC workflow files that were registered on master but have no benchmark code. Co-Authored-By: Noah Kiser <noah@computesdk.com>
- Share one platform run across per-provider matrix jobs by passing RUN_KEY to bench run --run-key in the sandbox-cpu-node workflow. - Remove the which node probe in cpu-node-workload.js; the script is already executing under Node, so the probe falsely reported a gap on sandboxes that lack the which utility. - Preserve version, timestamp, environment, and config fields when merge-results.ts combines cpu-node per-provider files, keeping the merged output aligned with results/schema.json. Co-Authored-By: Noah Kiser <noah@computesdk.com>
The add-mask loop used `[ -n "$v" ] && echo`, so any empty value left the while loop returning 1 and killed the whole CI step under `set -e`. Some providers legitimately have unset/empty keys in the vault, so guard empty keys/values and continue instead of failing. Co-Authored-By: Noah Kiser <noah@computesdk.com>
Co-Authored-By: Noah Kiser <noah@computesdk.com>
Co-Authored-By: Noah Kiser <noah@computesdk.com>
devin-ai-integration
Bot
force-pushed
the
sandbox-bench-cpu-node
branch
from
August 19, 2026 18:46
3f8df2b to
9319cf8
Compare
Co-Authored-By: Noah Kiser <noah@computesdk.com>
Co-Authored-By: Noah Kiser <noah@computesdk.com>
Co-Authored-By: Noah Kiser <noah@computesdk.com>
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
Adds the CPU-node sandbox benchmark (
cpu-node), a cross-provider CPU performance benchmark that runs a self-contained, stdlib-only Node.js workload inside a fresh sandbox and scores providers on wall-clock compute time.The branch originally wired the benchmark into the legacy
benchmarks/src/run.tsorchestrator, but that file was removed onmaster. This PR rebases the work and re-implements the runner integration as a@benchsdk/runner*.bench.tsentrypoint (benchmarks/sandbox/cpu-node.bench.ts), plus a legacy bridge that keeps the existing JSON/SVG results pipeline intact.What the benchmark measures
The in-sandbox workload is
benchmarks/scripts/cpu-node-workload.js. It is pure Node.js (nonode_modules, no native bindings) and runs the same deterministic compute phases on every provider:The workload emits a single
WorkloadResultJSON line with the total wall-clock time in milliseconds (valuelower-is-better, unitms).Scoring
benchmarks/sandbox/cpu-node.ts:computeStats:ok / total)scoreMetricconverts the median into a 0–100 score against aceilingof 45,000 ms:100 * (1 - median / ceiling).compositeScore=scoreBeforeReliability * successRate, so a provider that fails most runs cannot score highly.[0, 100].Architecture / files
benchmarks/sandbox/cpu-node.ts— workload orchestrator (runCpuNodeBenchmark), scoring, stats, result writer, and stdout parser.benchmarks/scripts/cpu-node-workload.js— the script that actually executes inside the sandbox.benchmarks/scripts/cpu-node-stdout.js— helper that emits theWorkloadResultJSON line and installs crash handlers.benchmarks/sandbox/cpu-node.bench.ts—@benchsdk/runnerentrypoint (defineBenchmarkConfig+defineTask).benchmarks/sandbox/cpu-node-legacy-results.ts— maps the runner'sParticipantRecords[]back into the existingCpuNodeBenchmarkResult[]shape and writesresults/cpu_node/<YYYY-MM-DD>.jsonpluslatest.json.benchmarks/sandbox/generate-cpu-node-svg.ts— renderscpu_node.svgfromresults/cpu_node/latest.json.benchmarks/scripts/smoke.ts— local smoke harness that runs the workload on the current machine (pnpm smoke:cpu-node).benchmarks/src/merge-results.ts— newmainHpc()merge path that groups per-providerlatest.jsonartifacts by suite directory, deduplicates, and writes combinedresults/<suite>/<date>.jsonwith schema-compliantversion,timestamp,environment, andconfigmetadata..github/workflows/sandbox-cpu-node.yml— CI workflow.CI workflow
masterthat touch the benchmark paths, plusworkflow_dispatchwithiterations,provider, anddry_runinputs.namespace-profile-defaultagainst a 28-provider matrix.npx tsx packages/benchsdk-runner/dist/bin.js run benchmarks/sandbox/cpu-node.bench.ts --provider <p> --iterations <n> --run-key "$RUN_KEY"whereRUN_KEYis${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}so all matrix jobs share one platform run and can be ranked against each otherresults/directory as an artifactcollectjob:results-*artifactsmerge-results.ts --input artifacts --mode benchmarkgenerate-cpu-node-svgto producecpu_node.svgpushordry_run)results/cpu_node/andcpu_node.svgback to the branchRemoved dangling workflows
The PR also deletes the sibling
sandbox-*.ymlworkflow files (sandbox-disk,sandbox-dns,sandbox-download,sandbox-latency,sandbox-memory,sandbox-network-localhost,sandbox-network-wan,sandbox-pgbench,sandbox-realworld,sandbox-system). These were registered onmasterbut referenced the deletedbenchmarks/src/run.tsandbuild-bundles.tstooling and had no runnable benchmark code.Running locally
Verification
pnpm typecheckpassespnpm test:benchmarkspassespnpm smoke:cpu-nodepassesAdditional fix
benchmarks/scripts/load-vault-secrets.shhad a brittle add-mask loop that returned a non-zero exit code whenever a matched vault key had an empty value, killing the whole CI step underset -e. The script now skips empty keys/values instead of failing, which keeps provider jobs that are missing a credential from crashing the vault-loading step before the benchmark can skip them cleanly.Link to Devin session: https://app.devin.ai/sessions/b6422a238bc0444b90e7af39407c6961
Requested by: @kisernl