Logs
Branching & release
prod ← dev ← feat/F-###, and the commit format.
docs/BRANCHING.md
Three long-lived branches, one short-lived branch per feature.
| Branch | Holds | Deploys to | Merges from |
|---|---|---|---|
prod | What is live. Only ever fast-forwarded from dev at a release. | Production (Kubernetes) | dev |
dev | The integration branch. Everything that has passed the gate. | Staging | feat/*, fix/*, chore/* |
main | The 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:
- One branch per feature id.
feat/F-020-projects, notfeat/stuff. The id ties the branch to a row in FEATURES.md and todata/dashboard/features.json. - 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
devwith a half-built feature nobody can use. npm run verifymust pass before the merge. No exceptions — that is the whole point of having a gate.- Merge with
--no-ff. The merge commit is the record that a feature landed as a unit. - Update the board in the same commit as the code.
features.jsonstatus, theupdatesentry, and theFEATURES.mdrow move together, or the board starts lying. prodonly ever moves forward fromdev. No direct commits, no cherry-picks. If something is wrong in production, fix it ondevand 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.