Start here
Adopt bay step by step
Try bay in small steps on your own repository, score the trial, and switch it off if needed.
Adopt bay in small steps, so you can undo every step. Check each machine first, then let bay merge into a scratch copy of main. Next, give bay one small repository or stream, and then main itself, one stream at a time. Write down how you will judge the trial before it starts.
bay keeps its state in Git refs, and every merge is a plain Git commit on main. So switching bay off removes a few settings and deletes no history.
When to use this page
- A first trial: you want to see bay on real changes before it merges into your main.
- A team decision: you need numbers that show whether bay helps your team.
- A way back: you want to know how to switch bay off before you switch it on.
The adoption ladder
Climb one rung at a time, and climb only when the scorecard says so. From each rung you can step back to the one below it.
| Rung | What runs | Risk to your main |
|---|---|---|
| 0. Readiness | bay doctor on each machine. Nothing merges. | None |
| 1. Beside your flow | bay checks and merges real changes into a scratch copy of main. Your current flow keeps merging main. | None: bay never writes your main |
| 2. Small | bay merges one non-critical repository or stream. | That repository or stream only |
| 3. Main | bay merges main, one stream at a time. The old tool retires last. | Earned by rungs 1 and 2 |
Rung 0: check each machine
Install bay and run bay doctor on each machine that runs agents or an executor. Fix each red row before you go on. Each red row names its fix.
bay doctorRung 1: merge beside your flow
Make a scratch copy of main, and let bay merge into that copy only. The cleanest copy is a separate repository, for example a new host from bay host init. Push main there, then commit .bay/config.toml and .bay/policy.toml to the copy. Agents in a clone of the copy start and merge changes as usual. Your real main never sees them. Send a share of real tasks through the copy, and compare the outcome with your current flow. Make a fresh copy when it falls far behind main.
# on the host: an empty repository for the trial
bay host init /srv/git/app-trial.git --trunk main
# in a fresh clone of your repository
git remote add trial ssh://git.example.com/srv/git/app-trial.git
git push trial main
# commit .bay/config.toml and .bay/policy.toml, push them to trial, then
bay install --trunk main --remote trialRung 2: one small stream
Pick one repository or stream that nothing urgent depends on. Follow the Quickstart on its real main. On a forge, let only the executor's identity push to that main.
Rung 3: main, stream by stream
Move one team or one group of agents onto bay at a time. On a forge, or a bay-hosted main without a key registry, commits from your old flow still reach main. bay watch --landed marks each of those commits with outside_bay. Retire the old tool when no stream uses it.
Score the trial
Write the scorecard before the trial starts, with a target for each measure. Measure the same weeks of your current flow, so you compare like with like. bay records the times and the check cost. People count interventions, wrongful blocks and recovery.
git fetch origin 'refs/bay/log/*:refs/bay/log/*' 'refs/notes/bay/*:refs/notes/bay/*'
git log --format='%cI %s' refs/bay/log/<executor> # one terminal record per operation
git notes --ref=bay/evidence/<producer> show <commit>^{tree} # the evidence of one merge, with at
bay status <change> # landing_cost and operation.cost| Measure | How to read it |
|---|---|
| Time from a green check to merged, p50 and p95 | Per merged change: the at of its passing evidence record, then the commit time of its terminal record in refs/bay/log/<executor>. The difference is the wait. |
| Human interventions per 100 merges | Count by hand each time a person acted so that a change could merge. Each refusal in bay status names its reason code, which helps the count. |
| Wrongful blocks | Review each refusal by hand. A refusal of a change that was correct and current counts as wrongful. |
| Recovery time | Count by hand the time from a broken main or a stuck queue to the next merge. bay status --lineage lists the Reverts: and Fixes: pairs on main. |
| Check compute per accepted change | bay status <change> shows landing_cost.worker_seconds, the check time on the merged result. operation.cost also counts discarded attempts. |
Switch bay off
Switching bay off takes a few steps and deletes no history. Afterwards, a plain git push to main works again.
- 01
Stop the executors
Stop every
bay executor runthrough its supervisor. A change still in the queue then stays unmerged. Its record stays underrefs/bay/changes/. - 02
Open main on a host from
bay host initRemove bay's two hooks and its main branch name from the host's Git config. Then Git on the host applies only its own rules again.
sh git --git-dir=/srv/git/app.git config --remove-section hook.bay-trunk git --git-dir=/srv/git/app.git config --remove-section hook.bay-scope git --git-dir=/srv/git/app.git config --unset bay.trunk - 03
Open main on a forge
Remove the branch protection or ruleset that lets only the executor's identity push to main. Keep any rule that refuses a force push to main.
- 04
Clean each agent machine
Follow the uninstall steps on the Install page, in each repository and then on the machine. Remove bay's hook entries first. While they stay, bay's hook refuses an agent's
git pushof main. When.claude/settings.jsonsits on main, push that change to main too. - 05
Push without bay
Push one commit to main with plain Git, and confirm that the remote takes it.
sh git push origin main
What stays after you switch off
- Every merge stays on main as a plain Git commit.
- Evidence stays under
refs/notes/bay/evidence/, andgit notesreads it. - Change records and executor logs stay under
refs/bay/. - No step above deletes a ref. Keep bay's refs on the remote, so the record stays whole.
Not built yet
- A shadow executor that checks real changes and records evidence, but never merges. Rung 1 uses a scratch copy instead.
- One command that reports the scorecard measures.
Limits
- One main branch takes at most 1,440 divided by the check minutes changes a day.