Merge pull request 'Playbook 06 — one feature, one branch, one MR per repo' (#22) from feat/feature-branch-workflow into main
This commit was merged in pull request #22.
This commit is contained in:
@@ -49,6 +49,7 @@ the expensive half.
|
||||
| [03](03-issues.md) | Issues | Something is wrong — often with the owner unknown |
|
||||
| [04](04-build-handoff.md) | Build handoff | A design is ready to be built |
|
||||
| [05](05-constitution-sync.md) | Constitution sync | `how-we-build.md` changed a rule the mesh enforces |
|
||||
| [06](06-feature-branches.md) | Feature branches across repos | Code changes, in one repo or several, need branching and merging |
|
||||
|
||||
## Status lives in frontmatter
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# Playbook 06 — Feature branches across repos
|
||||
|
||||
**Trigger.** Work that changes code — in one code repo or in several at once (`mesh-sdk`,
|
||||
`mesh-control`, `mesh-catalog`, `mesh-host`, `mesh-lab`, and `hq` when a decision rides along).
|
||||
|
||||
**Who runs it.** Anyone who writes code, engineers and agents alike. Agents follow it exactly —
|
||||
it is the guard against the failure it was written for.
|
||||
|
||||
## The failure it prevents
|
||||
|
||||
A feature was worked as a branch-and-MR per *unit of thought* — one per decision, one per
|
||||
stacked increment — and each MR was treated as finished when it was *opened*, not when it was
|
||||
*merged*. Across repos the same feature took a different branch name in each. The MRs piled up
|
||||
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.
|
||||
|
||||
## The rule
|
||||
|
||||
One feature is **one branch name**, **one worktree per repo**, **one MR per repo**, opened
|
||||
**once, at the end**.
|
||||
|
||||
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.
|
||||
2. **Isolate each repo.** One git worktree per touched repo under `.work/<slug>/<repo>`, branched
|
||||
off `main`:
|
||||
```
|
||||
git worktree add .work/<slug>/<repo> -b feat/<slug> origin/main
|
||||
```
|
||||
Parallel features never collide, and no shared checkout is edited.
|
||||
3. **Commit as you go — locally.** Increments land on the one branch. Nothing is pushed and no
|
||||
MR is opened mid-feature.
|
||||
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.
|
||||
5. **Merge promptly, once approved.** Every merge into `main` is notified and approved
|
||||
([ADR 0042](../../02-DECISIONS/0042-approval-is-the-checkpoint.md)); 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.
|
||||
|
||||
## What this is not
|
||||
|
||||
- **Not a licence to batch unbounded work.** A feature is a *bounded* unit; if it sprawls for
|
||||
days, end-of-feature bloat merely replaces per-increment bloat. Split it into features, each
|
||||
its own branch and MR.
|
||||
- **Not a second trunk.** Every repo branches off `main`. There is no longer an `initialization`
|
||||
trunk.
|
||||
|
||||
## How it is checked
|
||||
|
||||
The end state is visible, and its absence is the smell:
|
||||
|
||||
- After a feature merges, `git branch -r | grep feat/<slug>` and `git worktree list` return
|
||||
nothing for it. A surviving branch or worktree means step 6 was skipped.
|
||||
- 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.
|
||||
@@ -6,8 +6,8 @@ today almost entirely those of **Novox Mesh**, its first product ([ADR 0028](02-
|
||||
|
||||
Before changing anything here, read the playbooks in
|
||||
[`00-META/process/`](00-META/process/) — every workflow (research, graduation, design
|
||||
amendment, issues, build handoff, constitution sync) is documented there, and agents operate
|
||||
through them. Thin skills in `.claude/skills/` wrap these playbooks for invocation
|
||||
amendment, issues, build handoff, constitution sync, feature branches) is documented there, and
|
||||
agents operate through them. Thin skills in `.claude/skills/` wrap these playbooks for invocation
|
||||
(`hq-new-research`, `hq-graduate`, `hq-new-issue`, `hq-diagnose`, `hq-amend-design`,
|
||||
`hq-handoff`, `hq-sync-constitution`, `hq-status`); each defers to its playbook as
|
||||
authoritative and adds only the mechanical scaffolding.
|
||||
@@ -31,6 +31,12 @@ authoritative and adds only the mechanical scaffolding.
|
||||
constitution page is derived from it — see playbook
|
||||
[`05-constitution-sync.md`](00-META/process/05-constitution-sync.md). Never edit the
|
||||
derived page directly.
|
||||
- **One feature, one branch, one MR per repo.** A code change spanning one or more repos uses a
|
||||
single `feat/<slug>` shared across every repo it touches, isolated in `.work/<slug>/<repo>`
|
||||
worktrees off `main`; push and open MRs only when the whole feature is done, then merge
|
||||
promptly and delete the branch. Per-increment branches and MRs that pile up unmerged are the
|
||||
failure this prevents — see playbook
|
||||
[`06-feature-branches.md`](00-META/process/06-feature-branches.md).
|
||||
|
||||
## This repository is public
|
||||
|
||||
|
||||
Reference in New Issue
Block a user