How Laufwerk works
A process, a recorded run, and explicit boundaries around work.
A workflow describes the process
A workflow defines its input, the work to do and the result it returns. A run is one recorded execution of that workflow. You can inspect a run after the CLI process exits.
Host project ──copy──→ Workspace ──checked write-back──→ Host project
↑
Isolated session ←→ Model provider
↑
Workflow and recorded run
↓
Local StudioAgents and sessions
An agent configures a model, tools, instructions and permissions. A session is its conversation and execution environment. Session.run handles a single turn and its lifecycle. Session.open lets several turns and commands share a session, followed by an explicit close.
In the coding example, implementation and verification share one session and the same working files. A second independent review can use a read-only session when the task warrants it.
Workspaces and write-back
A workspace is an isolated working copy. Edits there do not immediately change the host project. Workspace.writeBack is the explicit step that returns the changes.
Write-back checks whether the original host tree changed since it was copied and refuses a conflict. Keep editors quiet during the actual copy; it is not an atomic filesystem transaction. An interrupted writer can require inspection and recovery.
The agent sees /workspace. The native agent must also be configured with sandboxConfig: { workDir: "workspace" }. A path mentioned in a prompt does not set its working directory.
Identity and repeated commands
The workflow's idempotencyKey maps input to an execution identity. The coding starter uses executionKey. The same key returns to the same recorded execution. New work needs a new key.
Each existing run keeps its original workflow bundle. Changing a TypeScript file changes future runs, not the code of a run already in progress. Do not generate random identities inside replayed work to try to force retries.
The Effect syntax you need
Laufwerk alpha.6 uses Effect v3. Schema validates input and output at runtime. Workflow.make declares the workflow contract; toLayer provides its implementation.
const layer = workflow.toLayer(input => Effect.gen(function* () {
const value = yield* someEffect;
return value;
}));This fragment illustrates composition, not a runnable file: someEffect stands for an Effect operation. yield* obtains the successful value or propagates the failure. It does not automatically make arbitrary code durable. Use the SDK's named operations and Effect Workflow Activities for durable work boundaries.
You can start with the complete generated workflow and learn this syntax as you change it. The Effect v3 docs are optional deeper reading.
Waiting is a normal state
A workflow can pause for a human response and continue in a later process. “Command succeeded” does not always mean “workflow completed.” A completed workflow can also return a business result such as declined. Inspect both state and result.