Skip to content

Spike: make Worker Shell effects transactional with the workflow journal #357

Description

@taras

Story

As an Executable.md workflow host implementor, I want one Worker Shell invocation to share the WorkflowRun's SQLite effect transaction, so the first production release can include a useful interpreted shell without weakening the rule that a Workspace mutation and its journal result publish atomically.

Context

#351 / PR #353 proves that Cloudflare Computer's Worker Shell model runs natively in Deno over the #349 DOFS Workspace:

  • just-bash is the interpreter;
  • Cloudflare's WorkspaceFsAdapter supplies filesystem and environment behavior;
  • a Deno Worker prevents CPU-bound shell code from starving the XMD host;
  • the interpreter has no host PATH or native-execution route; and
  • the measured containment suite produced no host filesystem escape.

That spike proves containment, availability isolation and cross-operation DOFS coherence. It does not prove the workflow durability boundary selected after the spike:

one expansion -> one effect -> one SQLite transaction

In PR #353, filesystem operations commit independently. Production Worker Shell can ship in xmd workflow only if every filesystem request in one invocation participates in the same operation-scoped transaction or unpublished copy-on-write root as its journal result.

Product contract under test

“Worker Shell” names the Workspace-scoped capability. just-bash is its initial engine, not a promise of native Bash or a permanent public engine choice.

XMD host
└── effect transaction + journal
    └── filesystem RPC boundary
        └── Deno Worker
            └── just-bash
                └── Cloudflare WorkspaceFsAdapter

The shell has no native executable, host PATH, writable FUSE or workerd dependency.

Successful execution

BEGIN
  shell filesystem RPCs mutate one transaction
  append the successful shell result
COMMIT

The next Workspace effect observes the committed mutations and journal result together.

Known failed execution

A nonzero exit, thrown error, timeout, cancellation or Deno Worker termination rolls filesystem mutations back to an effect-local savepoint, then records the failed result in the same outer transaction:

BEGIN
  SAVEPOINT shell_mutations
  shell filesystem RPCs
  ROLLBACK TO shell_mutations
  append the failed shell result
COMMIT

For example, this leaves no result.txt under xmd workflow:

echo partial > result.txt
false

Ordinary xmd run keeps its host-shell behavior and is not changed by this contract.

Host interruption

If the XMD host disappears with the SQLite transaction open, SQLite recovery rolls back the whole transaction. Restart finds neither published filesystem mutations nor a journal result, so replay may execute the effect again under the same identity.

Proof slices

  1. Operation transaction — extend the Deno-local DOFS storage boundary so one caller owns an explicit transaction or unpublished root across multiple filesystem operations and can atomically append the journal result.
  2. Worker routing — route every Workspace filesystem RPC from one Deno Worker invocation to that exact transaction. Reject calls with a missing, completed, cancelled or foreign effect identity.
  3. Success publication — prove files, deletes, renames, modes, symlinks and the shell result become visible together after a zero exit.
  4. Failure rollback — prove nonzero exit, interpreter error, timeout, explicit cancellation and Worker.terminate() publish no filesystem mutation while retaining the failed result.
  5. Host-crash recovery — kill the compiled proof after at least one shell write but before result publication, restart against the same database and prove both mutation and result are absent.
  6. Isolation regression — retain PR 🔬 Spike: run Cloudflare Worker Shell and Worker JavaScript natively in Deno (#351) #353's host-file escape, missing-native-command, fabricated-environment, network refusal and CPU-spin probes at the new boundary.
  7. Replay shape — prove a committed result restores without starting a Worker and an uncommitted crash reruns against the pre-effect Workspace root.

Acceptance

  • One shell invocation has one stable workflow effect identity and one operation-scoped SQLite transaction.
  • All filesystem adapter calls for that invocation are fenced to its transaction.
  • Successful mutations and the filtered journal result commit atomically.
  • Every known failure path rolls mutations back and records the failure without opening a second top-level effect transaction.
  • A host crash rolls the entire open transaction back on restart.
  • A stale or late Worker message cannot mutate a completed, cancelled or different effect.
  • The Deno Worker still preempts a CPU-bound interpreter without blocking the host event loop.
  • The capability still exposes no native execution, host PATH, host filesystem or default network route.
  • The proof runs from one documented command and records reproducible evidence.
  • The issue reports a binary verdict: include Worker Shell in the first production release, or defer it without weakening workflow durability.

Intentionally excluded

  • Production <Workspace> or shell-component implementation.
  • Worker JavaScript.
  • Native subprocesses or writable FUSE.
  • Bundled workerd or Cloudflare Containers.
  • External side-effect atomicity; Git push, forge APIs and Agent providers reconcile separately.
  • Changing ordinary xmd run shell semantics.

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions