Files
hq/00-META/process/07-feature-branches.md
T
jschoubben 1111bd84d7 Establish the repo for the completed Phase 0-3 build
Settles the design repository now that the self-upgrade build is on main:
- Records the two decisions that shipped without a record — ADR 0077 (the
  controller/foundation/node vocabulary) and ADR 0078 (the store and broker are
  ordinary modules); accepts ADR 0075 and 0076, which shipped work rests on.
- Fills issue 051's amended-design and wires ADR 0078 into 07-the-foundation.
- Sweeps the repo rename (mesh-control -> mesh-controller) into the mutable docs
  now that the forge repo is renamed; updates the glossary note and repos.md.
- Fixes the six broken links from the design-doc renames, indexes the glossary,
  regenerates the decisions reading order.

Both checks (records.py, index.py) are green. Statuses stay honest: the build is
on main and lab-proven but not deployed as the production mesh, so the to-be docs
remain in-progress and the as-is layer (the hal mesh) is unchanged — graduation
to implemented + as-is belongs to deployment, not merge.

https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
2026-09-17 00:04:58 +02:00

2.8 KiB

Playbook 07 — Feature branches across repos

Trigger. Work that changes code — in one code repo or in several at once (mesh-sdk, mesh-controller, 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 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.

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.