Skip to main content

Isolated workspace

During setup, loom run --local creates an isolated workspace: a disposable, on-disk snapshot where jobs execute. It separates execution from your live checkout and excludes ignored files. It does not isolate host processes or guarantee the same result as CI.

If a command fails, use the printed isolated workspace path to reproduce the command against the exact source snapshot. Use the receipt path in the live checkout to inspect persistent logs and published artifacts.

Why it exists

The snapshot lets you inspect and rerun commands against the source used by the run. Missing ignored files can expose dependencies on local state. Host tools, environment variables, user config, secrets, and external services can still affect the result.

When comparing with CI, match the source, tool versions or image digest and platform, variables, services, secrets, and external inputs. Uncommitted source in a local snapshot may differ from the source checked out in CI.

What gets snapshotted

Loom starts from HEAD and includes your uncommitted source changes:

SourceIncluded?Details
HEAD commitYesLoom clones the repo and checks out HEAD in detached mode
Modified tracked filesYesDirty changes to tracked files are copied into the snapshot
Added/renamed tracked filesYesStaged additions and renames are applied
Deleted tracked filesYesTracked deletions are removed from the snapshot
Untracked, non-ignored filesYesFiles visible to git status (not in .gitignore) are copied
Gitignored filesNoFiles matched by .gitignore are excluded
SymlinksPreservedSymlinks are copied as symlinks (targets are not dereferenced)
Non-regular filesNoDevices, sockets, and other special files are not supported

If a command behaves differently in the snapshot, check whether it depends on an ignored file that Loom excluded.

How to use it

1. Find the path

Local runs print the isolated workspace path near the start of output:

isolated workspace: /tmp/loom-run-local-1772666574190575000-3847261095

Copy this path when you need to inspect or rerun against the source snapshot.

2. Inspect the snapshot

The snapshot looks like a normal repo checkout. It is the execution workspace, not the persistent runtime-artifact destination:

/tmp/loom-run-local-<run_id>-*/
apps/
libs/
packages/
.git/ # real git clone (detached HEAD)

3. Check run artifacts

After the run completes, start debugging from .loom/.runtime/ in the live checkout. Loom publishes runtime outputs there so they survive independently of the disposable snapshot:

ArtifactPathWhat it tells you
Receipt.loom/.runtime/receipts/<receipt>.jsonRun metadata, status, pointers to logs
Pipeline summary.loom/.runtime/logs/<run_id>/pipeline/summary.jsonOverall pass/fail, job statuses
Job manifest.loom/.runtime/logs/<run_id>/jobs/<job_id>/manifest.jsonPointers to the failing step's events
Step events.loom/.runtime/logs/<run_id>/jobs/<job_id>/user/execution/script/<NN>/events.jsonlDetailed output for a specific step
Job artifacts.loom/.runtime/logs/<run_id>/jobs/<job_id>/artifacts/Published files when artifacts: is configured

The pointer fields form the stable diagnostic structure; concrete receipt names, run IDs, timestamps, and absolute paths are specific to each run. For a failed user step, follow the receipt's logs_dir to pipeline/manifest.json, then follow failing_job_manifest_path to the job manifest and failing_step_events_path to the existing user/execution/script/<NN>/events.jsonl file.

For the full navigation flow, see Runtime logs and Receipts.

4. Reproduce failures

Before changing anything in your main checkout, try reproducing from inside the isolated workspace:

cd /tmp/loom-run-local-<run_id>-*
loom run --local --workflow .loom/workflow.yml

This starts another run from that source snapshot. Environment variables, tools, configuration, and external services can still differ. Check those inputs as well as files when reproducing a failure.

Disk usage and cleanup

Because each snapshot is a full copy of your repo, it can use significant disk space for large repositories.

BehaviorDetails
LocationOS temp directory (e.g., /tmp/loom-run-local-<run_id>-*)
On preparation failureSnapshot directory is cleaned up automatically
On run success or failureSnapshot is preserved for debugging
Manual cleanupDelete the directory when done — it is fully disposable

Deleting the snapshot does not delete receipts, structured logs, or published job artifacts in the live checkout's .loom/.runtime/ directory.

Common pitfalls

PitfallFix
Debugging in your original checkout instead of the snapshotAlways cd into the printed isolated workspace path first
Depending on a gitignored file (e.g., .env.local)Commit the file, pass values via variables:, or generate it in a script: step
Assuming "snapshot" means remote executionThe snapshot is for local reproducibility only — it does not imply remote execution
Referencing ~/... paths during debuggingStay within the snapshot directory to reproduce what Loom actually ran

Example: gitignored file causes failure

A common "it works on my machine" scenario:

  1. You have a gitignored config file (e.g., .env.local) in your checkout.
  2. Your script reads it implicitly (directly, or via tooling that auto-loads it).
  3. The isolated workspace does not include that file, so the job runs with different configuration and fails.

Fix options:

  • Commit the config if it's not sensitive.
  • Pass values explicitly via workflow or job variables: — see Variables.
  • Generate the file inside the job as an explicit script: step (avoid printing secrets).

Privacy and secrets

Treat the isolated workspace as potentially sensitive:

  • It contains your source code and command-generated files.
  • The live checkout's .loom/.runtime/ may contain logs and published artifacts with environment details, commands, and error output.
  • Loom redacts exact secret matches in supported console, log, and receipt output. Transformed values and raw artifacts are outside that protection; review them before sharing externally.

See Receipts for guidance on what's safe to share.

Docker workspace mount modes

When Docker jobs execute inside the isolated workspace, the workspace is mounted into the container using one of two modes:

  • bind_mount — the isolated workspace directory is bind-mounted directly into the container at /workspace. Artifact matching reads that snapshot after execution.
  • ephemeral_volume (default) — a Docker volume is created and seeded with the snapshot. Candidate artifact roots are exported to private staging before the volume is removed; Loom then applies includes and excludes and publishes only selected files to the persistent destination.

Configure with the --docker-workspace-mount flag, LOOM_DOCKER_WORKSPACE_MOUNT environment variable, or runtime.docker.workspaceMount in repo or user config, in that precedence order. See Docker provider for details.

  • Runtime logs — how to navigate the persistent structured log tree in the live checkout
  • Receipts — run metadata and pointers to recorded evidence
  • Variables — pass configuration into jobs without relying on local files
  • Cache — cached outputs are restored inside the isolated workspace
  • Docker provider — workspace mount modes and container behavior
  • CLI loom run — full flag reference for local runs