Blocker
With RELAYFLOWS_SANDBOX_PROVIDER=daytona, a workflow's deterministic steps cannot do real work:
- Separate sandboxes per step.
process-backend-executor.ts calls backend.createEnvironment(step.name) inside every executeDeterministicStep, and createSandboxProcessBackend maps each createEnvironment to a fresh runtime.launch(). Two deterministic steps that must see the same tree (write a file, then read it back) run in two disconnected sandboxes — unlike the local path, where every step shares one machine and one cwd.
- No source or workdir sync. Nothing uploads the runner's source into the sandbox. The step's local
cwd (e.g. /Users/…/repo) is passed verbatim to runtime.exec, where it does not exist — every command fails or runs against the wrong tree.
- No sandbox identity. The provisioned sandbox's exact ID is never exposed to the command (nor bound into step output), so evidence cannot be tied to the sandbox that produced it, and a crashed run leaves unattributed sandboxes behind.
Net effect: a clean Daytona process backend is unusable for deterministic workflows — each step silently provisions a fresh, empty, anonymous sandbox and fails.
Reproducer (released @relayflows/cli 1.1.4, Daytona provider)
A two-step deterministic workflow in a git repo: step 1 asserts the synced source is present and writes $RELAYFLOWS_SANDBOX_ID to a file; step 2 reads it back and asserts the same ID and a bound RELAYFLOWS_SOURCE_COMMIT/RELAYFLOWS_TREE_DIGEST. Baseline: FAILED at step 1 (cwd missing remotely, no source, no ID). Evidence to be attached.
Requested fix (fail-closed)
- One shared sandbox per run for deterministic steps, matching local semantics.
- The exact source (git archive of HEAD) and workdir synced into it, with the source commit and tree digest bound into every step and stamped as sandbox labels.
- The exact sandbox ID exposed to every command (
RELAYFLOWS_SANDBOX_ID).
- Fail closed: if the source cannot be bound (no git repo), uploaded, or verified, the step refuses to run rather than executing in a desynced sandbox; a step whose cwd escapes the synced source root refuses too.
- Cleanup: the shared sandbox is destroyed at run end, verifiably (get-by-ID → Not Found, absent from full inventory).
Blocker
With
RELAYFLOWS_SANDBOX_PROVIDER=daytona, a workflow's deterministic steps cannot do real work:process-backend-executor.tscallsbackend.createEnvironment(step.name)inside everyexecuteDeterministicStep, andcreateSandboxProcessBackendmaps eachcreateEnvironmentto a freshruntime.launch(). Two deterministic steps that must see the same tree (write a file, then read it back) run in two disconnected sandboxes — unlike the local path, where every step shares one machine and one cwd.cwd(e.g./Users/…/repo) is passed verbatim toruntime.exec, where it does not exist — every command fails or runs against the wrong tree.Net effect: a clean Daytona process backend is unusable for deterministic workflows — each step silently provisions a fresh, empty, anonymous sandbox and fails.
Reproducer (released @relayflows/cli 1.1.4, Daytona provider)
A two-step deterministic workflow in a git repo: step 1 asserts the synced source is present and writes
$RELAYFLOWS_SANDBOX_IDto a file; step 2 reads it back and asserts the same ID and a boundRELAYFLOWS_SOURCE_COMMIT/RELAYFLOWS_TREE_DIGEST. Baseline: FAILED at step 1 (cwd missing remotely, no source, no ID). Evidence to be attached.Requested fix (fail-closed)
RELAYFLOWS_SANDBOX_ID).