# Run bay without an executor

> A small team can merge with bay from its own machines, with no executor to host or keep running.

Source: https://getbay.io/docs/no-executor (HTML).

A small team can use bay with no executor at all. `bay land --wait` runs the whole merge on the machine that asks for it. It builds the candidate, runs the checks, and pushes the result to main. Nothing else has to stay on, and your clone stays on your own machines.

This suits a few people with a few changes a day. A fleet of agents that should submit and leave still needs an executor.

## When to use it

- **A small team**: two or three people, each merging their own work from their own machine.
- **A private repository**: you would rather not clone it onto a shared box.
- **A first trial**: try bay before you decide where an executor should run.

## Merge from your machine

Run `bay land --wait` from the change's view. It returns the real outcome: merged, refused with a reason, or failed. Checks run in the sandbox on your machine: `bwrap` on Linux, `sandbox-exec` on macOS. Without a key registry, the merge is unsigned, and results say `trust: unsigned`. Leave `[executor] command` out of `.bay/config.toml`. With it set, `bay land --wait` first submits to that command, and fails when the command cannot take it.

```sh
bay land --wait
```

> While main is held, `bay land --wait` returns `queued` with `TRUNK_HELD`, and merges nothing.
> Run it again once the hold clears. A fix or an undo merges during a hold.

## Save edits from your main checkout

`bay save <intent>` merges the edits in your main checkout, the folder you cloned, as one change. It suits a person who edits files in place, with no `bay start` and no view. It takes every changed, new and deleted file, except files Git ignores. It opens a change with those files as its paths, and never commits on your branch. Then it runs `bay land --wait`, so it merges the same way, with or without an executor. After the merge, your checkout fast-forwards to the new main when nothing is in the way.

```sh
bay save CARD-123 --message "Fix the footer"   # --message is optional
```

> `--message` sets the first draft's message. The commit on main keeps bay's own message.
> A save under an intent that already merged opens a new change for it.
> If your checkout is off the main branch, or files changed during the save, it stays where it was.
> Then `detail.checkout` says why, and main already holds the saved edits.

### When bay refuses a save

A refused save leaves every file in your checkout exactly as it was. When it opened a change, the result names it under `change`, and the change stays open. Run `bay save` again with the same intent to retry. It reuses that open change. A change that waits for an approval returns `APPROVAL_PENDING` with `detail.queued`. Save again once approved. When main changed the same lines, it refuses with `MERGE_CONFLICT`. Bring those files up to main, then redo your edits.

- It runs only in the main checkout, never in a change's view or another worktree. In a view, run `bay land`.
- It refuses while a merge, rebase, cherry-pick or revert is under way.
- It refuses a file with an unresolved conflict, and a submodule.
- It refuses when your `HEAD` holds a commit that main lacks.
- Each of these fails before bay opens a change, and changes nothing.
- With nothing to save, it returns `ok` and merges nothing.

## If your machine sleeps

The push to main is one atomic step, so main never gets half a merge. When the machine wakes, `bay land --wait` reads the change's record and goes on. If main moved, it checks again. If its own lease ran out, it takes it back. If it slept after the push, bay reads the first result and never merges twice. Until the machine wakes, the change waits, unless you also run an executor, which may finish it for you.

## Approvals without an executor

An approval counts only with a key registry and an enrolled approver key. By default, a registry also makes each merging machine sign as executor and producer. To sign only approvals, set `[policy] signing = "approvals"` in `.bay/policy.toml` on main. Then merging machines need no keys, and merges and check records run unsigned. Only each approver enrols a key, in the registry's `approver` file. Keys and the registry explains this mode. Require a person's approval shows how to record a yes.

## When to add an executor

- **Agents should leave**: an executor finishes each merge after `bay land` returns at once.
- **Machines sleep or move**: an always-on executor keeps merges going.
- **More changes a day**: the throughput settings need executors to run checks side by side.
- **Targets that follow main**: only `bay executor run` moves a target that sets `advance = true`.

> Executors shows how to run one on a box or in your CI.

## Limits

- An operation's lease lasts `[executor] lease_s`, 60 seconds by default.
