You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The following modules SHALL be classified as Deferred (Tier 4): `net`, `tls`, `readline`, `perf_hooks`, `async_hooks`, `worker_threads`, `diagnostics_channel`. The following modules SHALL be classified as Unsupported (Tier 5): `dgram`, `http2` (full), `cluster`, `wasi`, `inspector`, `repl`, `trace_events`, `domain`.
Copy file name to clipboardExpand all lines: CLAUDE.md
+19Lines changed: 19 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -55,6 +55,16 @@
55
55
- track development friction in `docs-internal/friction.md` (mark resolved items with fix notes)
56
56
- see `.agent/contracts/README.md` for the full contract index
57
57
58
+
## Shell & Process Behavior (POSIX compliance)
59
+
60
+
- the interactive shell (brush-shell via WasmVM) and kernel process model must match POSIX behavior unless explicitly documented otherwise
61
+
-`node -e <code>` must produce stdout/stderr visible to the user, both through `kernel.exec()` and in the interactive shell PTY — identical to running `node -e` on a real Linux terminal
62
+
-`node -e <invalid>` must display the error (SyntaxError/ReferenceError) on stderr, not silently swallow it
63
+
- commands that only read stdin when stdin is a TTY (e.g. `tree`, `cat` with no args) must not hang when run from the shell; commands must detect whether stdin is a real data source vs an empty pipe/PTY
64
+
- Ctrl+C (SIGINT) must interrupt the foreground process group within 1 second, matching POSIX `isig` + `VINTR` behavior — this applies to all runtimes (WasmVM, Node, Python)
65
+
- signal delivery through the PTY line discipline → kernel process table → driver kill() chain must be end-to-end tested
66
+
- when adding or fixing process/signal/PTY behavior, always verify against the equivalent behavior on a real Linux system
67
+
58
68
## Compatibility Project-Matrix Policy
59
69
60
70
- compatibility fixtures live under `packages/secure-exec/tests/projects/` and MUST be black-box Node projects (`package.json` + source entrypoint)
@@ -63,6 +73,13 @@
63
73
- the matrix runs each fixture in host Node and secure-exec and compares normalized `code`, `stdout`, and `stderr`
64
74
- no known-mismatch classification is allowed; parity mismatches stay failing until runtime/bridge behavior is fixed
65
75
76
+
## Tested Package Tracking
77
+
78
+
- the Tested Packages section in `docs/nodejs-compatibility.mdx` lists all packages validated via the project-matrix test suite
79
+
- when adding a new project-matrix fixture, add the package to the Tested Packages table
80
+
- when removing a fixture, remove the package from the table
81
+
- the table links to GitHub Issues for requesting new packages to be tracked
82
+
66
83
## Test Structure
67
84
68
85
-`tests/test-suite/{node,python}.test.ts` are integration suite drivers; `tests/test-suite/{node,python}/` hold the shared suite definitions
@@ -97,6 +114,8 @@ Follow the style in `packages/secure-exec/src/index.ts`.
97
114
-`docs/runtimes/python.mdx` — update when PythonRuntime options/behavior changes
98
115
-`docs/system-drivers/node.mdx` — update when createNodeDriver options change
99
116
-`docs/system-drivers/browser.mdx` — update when createBrowserDriver options change
117
+
-`docs/nodejs-compatibility.mdx` — update when bridge, polyfill, or stub implementations change; keep the Tested Packages section current when adding or removing project-matrix fixtures
118
+
-`docs/cloudflare-workers-comparison.mdx` — update when secure-exec capabilities change; bump "Last updated" date
| **`fs`** | 🟡 Core I/O: `readFile`, `writeFile`, `appendFile`, `open`, `read`, `write`, `close`, `readdir`, `mkdir`, `rmdir`, `rm`, `unlink`, `stat`, `lstat`, `rename`, `copyFile`, `exists`, `createReadStream`, `createWriteStream`, `writev`, `access`, `realpath`. Missing: `cp`, `glob`, `opendir`, `mkdtemp`, `statfs`, `readv`, `fdatasync`, `fsync`. Deferred: `watch`, `watchFile`, `chmod`, `chown`, `link`, `symlink`, `readlink`, `truncate`, `utimes`. Full coverage planned. | 🟡 In-memory VFS only. `/bundle` (read-only), `/tmp` (writable, ephemeral per-request), `/dev` devices. Missing: `watch`, `watchFile`, `globSync`, file permissions/ownership. All operations synchronous regardless of API style. Timestamps frozen to Unix epoch. 128 MB max file size. | **secure-exec**: Permission-gated; filesystem behavior determined by system driver (host FS or VFS). Read-only `/app/node_modules` overlay. **CF**: No persistent storage; `/tmp` contents isolated per request and lost after response; no real permissions or ownership. |
44
-
|**`http`**| 🟡 `request`, `get`, `createServer` with bridged request/response classes. Fetch-based, fully buffered. No connection pooling, no keep-alive tuning, no WebSocket upgrade, no trailer headers. `Agent` is stub-only. | 🟡 `request`, `get`, `createServer` via fetch API wrapper. Requires extra compat flags. No `Connection` headers, no `Expect: 100-continue`, no socket-level events (`socket`, `upgrade`), no 1xx responses, no trailer headers. `Agent` is stub-only. ||
43
+
|**`fs`**| 🟢 Core I/O: `readFile`, `writeFile`, `appendFile`, `open`, `read`, `write`, `close`, `readdir`, `mkdir`, `rmdir`, `rm`, `unlink`, `stat`, `lstat`, `rename`, `copyFile`, `exists`, `createReadStream`, `createWriteStream`, `writev`, `access`, `realpath`, `cp`, `glob`, `opendir`, `mkdtemp`, `statfs`, `readv`, `fdatasync`, `fsync`, `chmod`, `chown`, `link`, `symlink`, `readlink`, `truncate`, `utimes`. Deferred: `watch`, `watchFile`. | 🟡 In-memory VFS only. `/bundle` (read-only), `/tmp` (writable, ephemeral per-request), `/dev` devices. Missing: `watch`, `watchFile`, `globSync`, file permissions/ownership. All operations synchronous regardless of API style. Timestamps frozen to Unix epoch. 128 MB max file size. |**secure-exec**: Permission-gated; filesystem behavior determined by system driver (host FS or VFS). Read-only `/app/node_modules` overlay. **CF**: No persistent storage; `/tmp` contents isolated per request and lost after response; no real permissions or ownership. |
44
+
|**`http`**| 🟡 `request`, `get`, `createServer` with bridged request/response classes. Fetch-based, fully buffered. `Agent` with connection pooling and per-host `maxSockets` limits. HTTP upgrade (101 Switching Protocols) support. Trailer header support on `IncomingMessage`. No keep-alive tuning, no WebSocket data framing. | 🟡 `request`, `get`, `createServer` via fetch API wrapper. Requires extra compat flags. No `Connection` headers, no `Expect: 100-continue`, no socket-level events (`socket`, `upgrade`), no 1xx responses, no trailer headers. `Agent` is stub-only. ||
45
45
|**`https`**| 🟡 Same contract and limitations as `http`. | 🟡 Same wrapper model and limitations as `http`. ||
|**`net`**| 🔵 Planned. | 🟡 `net.connect()` / `net.Socket` for outbound TCP via Cloudflare Sockets API. No `net.createServer()`. |**CF**: Outbound TCP connections supported. **secure-exec**: On roadmap. |
@@ -56,7 +56,7 @@ All three CF deployment models share the same `nodejs_compat` API surface. WfP a
56
56
|**`process`**| 🟢 `env` (permission-gated), `cwd`/`chdir`, `exit`, timers, stdio event emitters, `hrtime`, `platform`, `arch`, `version`, `argv`, `pid`, `ppid`, `uid`, `gid`. | 🟡 `env`, `cwd`/`chdir`, `exit`, `nextTick`, `stdin`/`stdout`/`stderr`, `platform`, `arch`, `version`. No real process IDs or OS-level user/group IDs. Requires extra `enable_nodejs_process_v2` flag for full surface. |**secure-exec**: Configurable timing mitigation (`freeze` mode); real `pid`/`uid`/`gid` metadata. **CF**: Synthetic process metadata. |
57
57
|**`child_process`**| 🟢 `spawn`, `spawnSync`, `exec`, `execSync`, `execFile`, `execFileSync`. `fork` unsupported. | 🔴 Non-functional stub; all methods throw. |**secure-exec**: Bound to the system driver; subprocess behavior determined by driver implementation. CF has no subprocess support. |
|**`vm`**| 🔴 Browser polyfill via `Function()`/`eval()`. No real context isolation; shares global scope. | 🔴 Non-functional stub. | Neither offers real `vm` sandboxing. secure-exec polyfill silently runs code in shared scope, not safe for isolation. |
@@ -91,13 +91,13 @@ All three CF deployment models share the same `nodejs_compat` API surface. WfP a
|**`async_hooks`**|🔴 Stub: `AsyncLocalStorage` (run/enterWith/getStore/disable/exit), `AsyncResource` (runInAsyncScope/emitDestroy), `createHook` (returns enable/disable no-ops), `executionAsyncId`/`triggerAsyncId`. All methods are callable but do not track real async context. | 🔴 Non-functional stub. ||
To request a new package be added to the test suite, [open an issue](https://github.com/rivet-dev/secure-exec/issues/new?labels=package-request&title=Package+request:+%5Bpackage-name%5D).
0 commit comments