kern-sandbox 0.1.16 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +13 -11
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -36,7 +36,7 @@ const crypto = require("crypto");
36
36
  const zlib = require("zlib");
37
37
  const { spawn, spawnSync } = require("child_process");
38
38
 
39
- const VERSION = "0.1.16";
39
+ const VERSION = "0.1.17";
40
40
 
41
41
  const DEFAULT_IMAGE = "python:3.12-slim";
42
42
  const WORKSPACE = "/workspace"; // where the persistent workspace is mounted inside every box
@@ -1060,11 +1060,13 @@ class Sandbox {
1060
1060
  const stderr = err.buffer().toString("utf8");
1061
1061
  const rc = toRc(code, signal);
1062
1062
  const fault = this._classify(rc, signal, stderr, timedOut, timeoutS);
1063
- // A box that FAILED TO START (kern exits 125) ran no user code, so REJECT rather than resolve a
1064
- // hollow ExecutionResult (empty stdout, exit 125). Mirrors the mount/config errors this SDK
1065
- // already throws up front; runtime events where the code DID run (timeout, OOM, escape) stay as
1066
- // data on `.fault`.
1067
- if (fault && fault.type === "startup_failed") {
1063
+ // A box that FAILED TO START ran no user code, so REJECT rather than resolve a hollow
1064
+ // ExecutionResult (empty stdout). Gated on `rc === 125` (kern's box-not-started code) AND the
1065
+ // startup_failed classification (which requires kern's own stderr marker): the confident pair
1066
+ // that tells a genuine box-not-started apart from a workload that itself exited 125 (no marker ->
1067
+ // fault null -> a normal result). An older kern (127) is returned as a data fault, not thrown.
1068
+ // Runtime events where the code DID run (timeout, OOM, escape) stay as data on `.fault`.
1069
+ if (rc === 125 && fault && fault.type === "startup_failed") {
1068
1070
  return reject(new SandboxError(fault.message || "the box failed to start"));
1069
1071
  }
1070
1072
  const files = before ? this._diff(before) : [];
@@ -1139,11 +1141,11 @@ class Sandbox {
1139
1141
  return sandboxFault("killed", "the box was killed (SIGKILL) - likely out of memory (exit 137)");
1140
1142
  if (rc === EXIT_SIGTERM || signal === "SIGTERM")
1141
1143
  return sandboxFault("timeout", "the box exceeded its time limit (reaped by kern's timeout backstop)");
1142
- // DETERMINISTIC box-not-started: kern exits 125 (Docker's convention) when it could not BUILD the
1143
- // box (a mount refused at runtime, an unmappable --user, a seccomp/AppArmor/cgroup setup error), so
1144
- // the workload never ran. Decided by exit code, no stderr marker needed; the caller REJECTS on it.
1145
- if (rc === 125) return sandboxFault("startup_failed", stderr.trim().slice(0, 500) || "the box failed to start");
1146
- // LAST resort heuristic (also catches an OLDER kern that still exits 127 for a setup failure).
1144
+ // Box-not-started: a non-zero exit whose stderr carries kern's OWN setup markers (printed by the
1145
+ // PARENT before the box runs). kern's box-not-started paths BOTH exit 125 AND print a `kern:` marker,
1146
+ // so `rc === 125 && marker` is the reliable signal - the marker is REQUIRED so a workload that merely
1147
+ // exits 125 ITSELF (the code ran and chose 125) is NOT mislabeled. `finish` REJECTS only on rc===125;
1148
+ // a non-125 startup_failed (an older kern's 127, or a forged marker) is returned as DATA, not thrown.
1147
1149
  if (rc !== 0 && looksLikeStartupFailure(stderr))
1148
1150
  return sandboxFault("startup_failed", stderr.trim().slice(0, 500));
1149
1151
  // Any other non-zero exit (incl. 139 SIGSEGV) is the USER's code failing - a normal Result.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kern-sandbox",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "kern is a fast, rootless sandbox and virtual resource runtime for any workload, including untrusted and AI-generated code; kern-sandbox is its Node/TypeScript binding. Run untrusted or agent-generated code (Python/JS/Bash) in a real, kernel-enforced box in single-digit milliseconds, with no cloud, no account and no VM.",
5
5
  "keywords": [
6
6
  "sandbox",