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
Add a module backend that runs ECMAScript sources in Dynamic Workers with structured input, retained execution events, durable filesystem access, and host-owned git and artifact capabilities.
Expose the backend on its own package subpath and cover it with unit and workerd integration tests.
The backend ID defines how `source` is interpreted. The shipped
16
-
container and worker backends treat it as shell syntax. Module backends
17
-
can use the same surface for structured code execution.
15
+
The backend ID defines how `source` is interpreted. Command runtimes accept shell syntax; module runtimes accept their documented programming language.
`input` is accepted by structured module backends and rejected by command
48
-
backends. `cwd` is the command working directory or, for module backends,
49
-
the base path for backend-specific resolution. A handle is single-consumer:
50
-
call `result()` or consume its event stream, not both. Repeated `result()`
51
-
calls return the same promise. `backend` records the resolved backend needed
52
-
for later reattachment.
45
+
`input` is accepted by structured module backends and rejected by command backends. `cwd` is the command working directory or the base for durable relative module imports. A handle is single-consumer: call `result()` or consume its event stream, not both. Repeated `result()` calls return the same promise. `backend` records the resolved backend needed for later reattachment.
Command backends leave `value` unset. Module backends can use `value` for a
73
-
structured return value. A command can complete while its post-command pull
74
-
fails; in that case `sync.status` is `"pending"`, and a configured
75
-
`SyncRetryScheduler` can durably retry the pull without rerunning the
76
-
command.
65
+
Command backends leave `value` unset. `isolate-javascript` uses `value` for the module's structured return value and reports a zero-entry completed sync. A command can complete while its post-command pull fails; in that case `sync.status` is `"pending"`, and a configured `SyncRetryScheduler` can durably retry the pull without rerunning the command.
77
66
78
67
## Backend routing
79
68
@@ -85,11 +74,17 @@ await workspace.runtime.exec("grep -R TODO .", {
Omitting `backend` selects the first configured backend. Backend selection is
91
-
routing, not authorization; public gateways must validate it against
92
-
server-side policy.
87
+
Omitting `backend` selects the first configured backend. Backend selection is routing, not authorization; public gateways must validate it against server-side policy.
93
88
94
89
## Command synchronization
95
90
@@ -99,24 +94,16 @@ Command backends continue to use the existing synchronization bracket:
99
94
push → spawn → events/result → pull
100
95
```
101
96
102
-
A backend with `sync: "none"`, such as `isolate-shell`, shares the host
103
-
store and reports zero push/pull counts. A container has its own VFS and
104
-
synchronizes changes before and after command execution. Fully draining
105
-
either `result()` or the event stream completes the post-command pull before
106
-
the stream closes.
97
+
A backend with `sync: "none"`, such as `isolate-shell`, shares the host store and reports zero push/pull counts. A Container has its own VFS and synchronizes changes before and after command execution. Fully draining either `result()` or the event stream completes the post-command pull before the stream closes.
107
98
108
-
Module backends use host capability calls against the authoritative
109
-
Workspace and therefore require no push/pull round trip.
99
+
Module backends use host capability calls against the authoritative Workspace and therefore require no push/pull round trip.
110
100
111
101
## Lifecycle differences
112
102
113
-
`container-shell` provides computerd's retained process log, replay,
114
-
signals, and disposal.
103
+
`container-shell` provides computerd's retained process log, replay, signals, and disposal.
104
+
105
+
`isolate-javascript` provides a Workspace-owned execution journal, retained result/events, host cancellation, and explicit disposal. Active Workers cannot be serialized across host restart; orphaned running records are reconciled to failed.
106
+
107
+
`isolate-shell` intentionally preserves one-call, buffered-result behavior in this release. It does not retain executions for later reattachment or disposal. `timeoutMs` and a concurrent `killExec()` for a caller-supplied execution ID cooperatively abort just-bash at statement boundaries; by the time an ordinary `exec()` promise returns, the command has already settled. Use the Container or JavaScript isolate when detached execution and retained lifecycle are required.
Applications may register additional command or module backends under their own IDs. Backend IDs are part of the execution contract: changing the backend may change the source language.
The common result contains process-compatible output and an optional structured value:
46
+
47
+
```ts
48
+
interfaceWorkspaceRuntimeResult {
49
+
status:"completed"|"failed"|"cancelled";
50
+
exitCode:number;
51
+
stdout:Uint8Array|string;
52
+
stderr:Uint8Array|string;
53
+
value?:WorkspaceRuntimeValue;
54
+
pushed:number;
55
+
pulled:number;
56
+
skipped:SkippedEntry[];
57
+
}
58
+
```
59
+
60
+
Command backends leave `value` unset. Module backends use it for their structured return value.
61
+
62
+
`container-shell` retains the existing computerd process lifecycle. `isolate-javascript` keeps an execution journal in the Workspace database and retains events/results until `disposeExec`. Active isolate cancellation is host-driven by disposing the child Worker. An execution left running across a Workspace host restart is reconciled to failed because a live Worker capability cannot be serialized into SQLite.
63
+
64
+
`isolate-shell` intentionally retains its existing behavior in this release: it buffers a just-bash call to completion, does not retain cross-request events, and cannot reattach by ID. Callers that require supervised process behavior should use `container-shell`; callers that require a managed isolate should use `isolate-javascript`.
65
+
66
+
## Backend authority
67
+
68
+
There is no general `workspace.scope()` abstraction. Backend construction fixes maximum authority and module availability. A public gateway must validate which backend a signed capability is allowed to select.
69
+
70
+
For different authority levels, configure distinct backend instances:
71
+
72
+
```ts
73
+
newIsolateJavaScriptBackend({
74
+
id: "isolate-javascript-readonly",
75
+
loader: env.LOADER,
76
+
access: "read",
77
+
});
78
+
79
+
newIsolateJavaScriptBackend({
80
+
id: "isolate-javascript",
81
+
loader: env.LOADER,
82
+
access: "read-write",
83
+
});
84
+
```
85
+
86
+
The backend argument is never itself authorization.
87
+
88
+
See [17. Isolate JavaScript](./17_isolate_javascript.md) for module and trusted-package behavior.
0 commit comments