ADR-0001: Three-step Git flow (feature → develop → main)
- Status: Accepted
- Date: 2026-05-30
- Scope: core (all repos, every project)
Context
A project here typically spans several independent git repositories (e.g. the
Expenses ecosystem: expenses backend, expenses-web, expenses-admin, plus
this dev-handbook). Work needs a predictable path from “in progress” to “released to production”,
with a clear integration point and a production branch whose history is only
ever well-tested merges. Committing straight to a shared branch loses the
ability to gate integration and makes releases hard to reason about.
Decision
Every repo follows the same three-step branching flow:
feature/* → develop → main
feature/*— all active development; branched offdevelopbefore
any file is edited. Commit freely here.develop— integration branch; only receives--no-ffmerges from tested
feature branches, after the user explicitly approves.main— production; only receives--no-ffmerges from arelease/*
branch at release time. Tags live onmain.
Releases go through a release/vX.Y.Z branch cut from develop: bump the
version (pom.xml for a Java backend; package.json + lock for a frontend — each
repo’s version file is declared in the workspace handbook.json manifest), merge
--no-ff into main and tag, then merge --no-ff back into develop, delete
the release branch, and push develop main --tags together. The /release
skill automates this. Bump is MINOR if any feat: commit exists since the
last tag, otherwise PATCH.
Rules that follow (mechanics):
- Never commit directly to
developormain. - Each repo has an independent version history — versions need not match.
- A breaking wire-contract change releases clients-first. Independent versions
mean nothing sequences a cross-repo change except the plan. When a server change
alters a shape a deployed client already reads, every client ships before the
server, and that ordering is recorded in the ADR that owns the change — not left
in a branch name or a chat message. Server-first is safe only for a purely
additive change. The client that cannot be rolled back with a redeploy (a mobile
build in review) is the one that sets the pace. - Co-author footer on every AI-assisted commit, naming the assisting model:
Co-Authored-By: Claude <model name> <noreply@anthropic.com>
The behavioral agreements layered on this flow — approval before any
commit/merge/release, branching both repos for cross-repo work,
recap-before-phase — live in 0003-collaboration-working-agreements (kept
there, not restated here).
Consequences
mainis always a clean trail ofrelease: vX.Y.Zmerges; rollback = check
out the previous tag.developis the single “what’s next” truth the user gates on.- Slightly more ceremony per change (branch + two merges at release), accepted
in exchange for a legible production history.
Related
- 0002-i18n-both-locales — another standing rule enforced at merge time
- Automation: the
/releaseskill performs the release-branch dance.