Skip to content

Daytona process backend: deterministic steps each provision a separate, unsynced, anonymous sandbox #52

Description

@khaliqgant

Blocker

With RELAYFLOWS_SANDBOX_PROVIDER=daytona, a workflow's deterministic steps cannot do real work:

  1. 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.
  2. 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.
  3. 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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions