Developer docs
Logs

Branching & release

prod ← dev ← feat/F-###, and the commit format.

docs/BRANCHING.md

Three long-lived branches, one short-lived branch per feature.

BranchHoldsDeploys toMerges from
prodWhat is live. Only ever fast-forwarded from dev at a release.Production (Kubernetes)dev
devThe integration branch. Everything that has passed the gate.Stagingfeat/*, fix/*, chore/*
mainThe default branch — tracks dev. Exists so a clone lands somewhere sensible.—dev

The loop

git switch dev && git pull
git switch -c feat/F-020-projects        # one branch per feature id

# … build the slice: prisma model → api module → contract → ui → tests …

npm run verify                            # typecheck → lint → test → build
git commit                                # conventional commits, see below
git switch dev && git merge --no-ff feat/F-020-projects

Rules:

  1. One branch per feature id. feat/F-020-projects, not feat/stuff. The id ties the branch to a row in FEATURES.md and to data/dashboard/features.json.
  2. A branch is a vertical slice, not a layer. Prisma model → API module → contract → UI → tests, all in one branch. A branch that only touches the backend leaves dev with a half-built feature nobody can use.
  3. npm run verify must pass before the merge. No exceptions — that is the whole point of having a gate.
  4. Merge with --no-ff. The merge commit is the record that a feature landed as a unit.
  5. Update the board in the same commit as the code. features.json status, the updates entry, and the FEATURES.md row move together, or the board starts lying.
  6. prod only ever moves forward from dev. No direct commits, no cherry-picks. If something is wrong in production, fix it on dev and release again.

Commit format

Conventional commits, scoped by workspace:

feat(api): projects module with org scoping
feat(web): project list and detail
feat(contracts): project + budget schemas
fix(api): agency users could read unassigned projects
docs: record D-009 (Stripe over Paddle)
chore(deps): add stripe

Types: feat · fix · refactor · docs · chore · perf · test · breaking. Scopes: api · web · contracts · infra · none for repo-wide changes.

Release

git switch prod && git merge --ff-only dev && git tag v0.x.0

A release is a fast-forward and a tag. If the fast-forward is refused, prod has diverged — which should be impossible under rule 6, and means something needs investigating rather than forcing.