Say how several agents work one feature on one branch
mesh/merge-gate head c2d5323dea5a merged into trunk 21b79a04a283 — pass: the change touches no module of the mesh's graph
mesh/repo-check head c2d5323dea5a merged into trunk 21b79a04a283 — pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request

Feature 57 was first worked as a pull request per issue into protected
branches and lost most of a day waiting on merge checks. Record the issue
as the unit, a review and checks once at the end, landing by fast-forward
under a lock, and the lessons met on the way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 19:50:14 +00:00
co-authored by Claude Opus 5.5
parent 21b79a04a2
commit c2d5323dea
+47
View File
@@ -14,6 +14,10 @@ stacked increment — and each MR was treated as finished when it was *opened*,
unmerged: one session left **sixteen** stacked intermediate MRs that had to be consolidated and
closed by hand. An MR is a review checkpoint, not a scratchpad.
It failed the other way too. A large feature was worked as one pull request per issue into protected
integration branches, each waiting for the forge's merge check, again whenever another merge moved the
branch, and for a review. Most of a day went to waiting on checks while the code itself was ready.
## The rule
One feature is **one branch name**, **one worktree per repo**, **one MR per repo**, opened
@@ -22,6 +26,9 @@ One feature is **one branch name**, **one worktree per repo**, **one MR per repo
1. **Name the feature once.** `feat/<slug>`. The *same* branch name in every repo the feature
touches — never a different name per repo, never a fresh branch per increment within the
feature.
The feature branch is never protected and takes no pull request until step 4: a protected
branch forces a merge check on every merge into it, which is the waiting this playbook avoids.
2. **Isolate each repo.** One git worktree per touched repo under `.work/<slug>/<repo>`, branched
off `main`:
```
@@ -40,14 +47,51 @@ One feature is **one branch name**, **one worktree per repo**, **one MR per repo
```
3. **Commit as you go — locally.** Increments land on the one branch. Nothing is pushed and no
MR is opened mid-feature.
The unit of work is an **issue**. Each commit message names the issue it fixes, such as
"Keep the assignments on the bus (issue 652)". No pull request, merge check, review or delivery
per issue.
4. **Finish, then publish.** When the whole feature is done — every repo, tests green — push
every branch and open **one MR per touched repo**, together.
Each repository's change gets one independent review before its MR opens; the checks run once,
on those MRs, and the feature is delivered as one delivery plan (the MRs share the branch name,
so they are one delivery group, ADR 0239).
5. **Merge promptly, once approved.** Every merge into `main` is notified and approved
(ADR 0023); once it is, merge —
do not leave it sitting. The branch is deleted on merge.
6. **Leave nothing behind.** After the MRs merge, no `feat/<slug>` branch and no `.work/<slug>`
worktree survive.
## Working one feature with several agents
A large feature (a design's whole work) is fixed by several agents at once. The lead holds the
feature branch; the agents never push.
- **One feature worktree per repository, held by the lead.** Each agent works on a local branch of
its own, in a worktree of its own, branched from the feature branch's current head.
- **Land by fast-forward, under a lock.** An agent brings its branch up to the feature branch,
runs the repository's tests and `merge-check.sh` in its own worktree, then fast-forwards the
feature branch under a lock (`flock <feature worktree>.lock git -C <feature worktree> merge
--ff-only <its branch>`). If another agent landed first, it merges again and repeats.
- **At most five issues are being fixed at once.** When one lands, the next ready issue starts at
once; the design's table of what waits for what says which are ready.
- **An issue partly done goes back to `open`** with a note naming the commits that landed and what
is left, linked `depends-on` to what it waits for. An issue is never left in `fixing` while
nobody works on it. A finished issue stays in `fixing` until the feature's delivery, then is
resolved.
- **Two issues in one file:** keep both sides' behaviour; where both added tests or list lines in
one place, keep all of them. Never resolve code with a blind `git merge-file --union`: it can
interleave two functions' braces. Build and test after every resolution.
- **Fetch by name.** In a shared clone a plain `git fetch` may update only `main`. Fetch the
feature branch with an explicit refspec before branching from it or comparing against it, or an
agent merges a stale copy.
- **Report every ten minutes,** short, as a tree or a table: the issues done (of the total), each
issue being fixed with its active time (minutes since its agent was sent, from a start time
written down then, never guessed), the issues ready next, the ones waiting, and anything that
needs the operator. Times are local and absolute.
- **When this playbook meets a problem,** the lesson is added here, so the next feature avoids it.
## What this is not
- **Not a licence to batch unbounded work.** A feature is a *bounded* unit; if it sprawls for
@@ -64,6 +108,9 @@ The end state is visible, and its absence is the smell:
nothing for it. A surviving branch or worktree means step 6 was skipped.
- A bed run from `.work/<slug>/mesh-lab` that fails naming a `.work/<slug>/<repo>/…` path it
cannot find is a missing sibling worktree, not a mesh fault.
- A feature's issues show their commits on the feature branch (`git log --grep 'issue <n>'`), and no
pull request into the feature branch exists. A pull request per issue, or an agent waiting on a
merge check mid-feature, is the second failure above.
- More than one open MR in a repo that share no feature name, or a stack of MRs none of which is
merged, is the failure this playbook exists to prevent — stop and consolidate before opening
more.