Skip to main content
A recipe defines how to build a custom VM image for your agents. It pairs a base image with a provisioning script that installs your toolchain — languages, package managers, SDKs, and build tools. When you bake it, the platform creates a scratch VM from the base image, runs your provisioning script, and snapshots the result as a new image. Agents boot from this image, so everything your script installs is available immediately — no install step at spawn time.

Base images

Every recipe starts from a platform base image that includes Debian 12, Git, Node.js, Claude Code, Codex CLI, and the gh CLI. Your provisioning script adds everything else. Agents run as the murmur user with passwordless sudo, so a missing system package never strands a task — the agent can install it at runtime. A recipe makes that unnecessary: the bake pays the install cost once instead of on every spawn. Orgs that want a non-root agent can remove /etc/sudoers.d/murmur in their provisioning script.

Provisioning script

The script runs as root on the scratch VM during the bake. It installs your toolchain and exits. Anything you install ends up in the final image.

Secret allowlist

If your provisioning script needs credentials — for example, to install packages from a private registry — list the secret names in secret_allowlist. Only listed secrets are available during the bake.

Baking

This triggers a bake workflow that creates the image. The resulting image is bound to the placement — a GCE image lives in the placement’s GCP project, an AMI lives in the placement’s AWS account. See the custom images guide for a full walkthrough.

Automatic recipe updates

An agent that hits a missing tool can install it at runtime, but the next agent pays the same cost — the fix belongs in the recipe. Murmur ships a built-in service that closes that loop: every agent turn can report an image defect (a missing tool, a command not found, a package too old), and the service turns a report into the smallest recipe change that addresses it, rebuilds the image, boots the new image on a real VM to confirm the fix, and only then repoints the workspace at it. If that verification returns anything other than a pass, it rejects its own rollout and restores your recipe. It only acts on a report naming a concrete, durable defect — a tool absent, broken, or outdated. Platform bugs, missing permissions, and task-specific complaints are ignored, because no recipe change fixes them. Every step is a change-request, so the trail is permanent and reviewable after the fact: what changed in your recipe, why (the agent’s report, quoted), and which image each workspace moved to.

Reviewing instead of acting

To have the service open change-requests for you to approve rather than applying them itself, disable the tenant-binding that grants it write authority:
Both commands matter. The first stops the authority being granted; the second ends the service’s current run, which is still using the authority it started with. Run the second once per workspace where the service is running — murmur ls --developer service_profile/murmur-image-updater --workspace <workspace> lists them. Restore it with the exact inverse:
In review mode the service opens two change-requests per defect — the recipe fix, and the bake that rebuilds the image — and its report names the order to approve them in: recipe first, then the bake, then smoke-test the resulting image before approving the rollout. Approving the bake needs bake.create plus permission to assume the murmur-image-updater service profile and the workspace’s service account, so pick a reviewer who has them. To turn the service off entirely rather than narrow it, disable the flight: murmur delete flight murmur-image-update. That is reversible the same way.