Files
ctms/docs/branch-governance.md
T

341 lines
8.3 KiB
Markdown

# CTMS Git Branch Governance
## 1. Purpose
This document defines the long-term Git branch governance model for the CTMS repository.
The goals are:
- keep daily development efficient on `dev`
- keep `main` readable as the next major version baseline
- keep `release` stable and suitable for production maintenance
- make release, hotfix, and back-merge behavior explicit
This document is the default branch management policy unless a later written rule supersedes it.
## 2. Branch Roles
### `dev`
`dev` is the daily development and integration branch.
Use cases:
- feature development
- exploratory changes
- internal integration and verification
- non-release refactors
Characteristics:
- accepts frequent commits
- may contain incomplete but merge-approved work
- history can be relatively dense
### `main`
`main` is the candidate primary version branch.
Use cases:
- preparing the next formal release
- staging a version for full regression, acceptance, or external integration
- holding a clean version-level history of what is intended to go to production next
Characteristics:
- must remain deployable in principle
- should only receive changes that are judged release-candidate quality
- should be cleaner than `dev` in both content and history
### `release`
`release` is the long-lived production stability branch.
Use cases:
- current production version
- urgent production hotfixes
- maintenance of already released code
Characteristics:
- strongest stability requirement
- no routine feature development
- every production release should be identifiable by tag
## 3. Promotion Path
The default code promotion path is:
`feature/*` -> `dev` -> `main` -> `release`
Meaning:
- daily work enters `dev`
- stable milestone scope is promoted from `dev` to `main`
- approved release scope is promoted from `main` to `release`
Direct promotion that skips stages is discouraged and must be justified in writing.
## 4. Branch Entry Rules
### Changes allowed into `dev`
Allowed:
- feature branches
- refactors
- test improvements
- integration work
- exploratory work that has passed review
Requirements:
- code review completed
- no known blocking regression introduced intentionally without team alignment
- relevant tests pass at the feature or module level
### Changes allowed into `main`
Allowed:
- version-ready content promoted from `dev`
- tightly scoped fixes required to stabilize the next version
Requirements:
- scope is explicitly selected for the next release candidate
- regression testing has been run for the affected area
- release-risking incomplete work must be excluded
- merge should represent a coherent version increment, not random unfinished work
### Changes allowed into `release`
Allowed:
- approved production releases from `main`
- hotfixes for production incidents
Requirements:
- release checklist completed
- production-facing validation completed
- change is either a formal release or a critical maintenance fix
Routine feature work must not be merged directly into `release`.
## 5. Merge Strategy
### `feature/*` -> `dev`
Preferred strategy:
- pull request merge or rebase merge
Rules:
- branch should be reasonably scoped
- commit history can be preserved
- reviewer may require cleanup for obviously noisy commits
### `dev` -> `main`
Preferred strategy:
- squash merge
Rationale:
- preserve detailed development history on `dev`
- keep `main` at a version or milestone granularity
- avoid making `main` a duplicate of `dev` commit-for-commit
Rules:
- each merge to `main` should correspond to a named milestone, candidate, or release scope
- squash commit message should describe the version or milestone clearly
Recommended commit format:
- `release(main): prepare v1.2.0 candidate`
- `release(main): integrate Q2 CTMS milestone`
### `main` -> `release`
Preferred strategy:
- normal merge commit
Rationale:
- preserve the relationship between the released state and the accepted candidate branch
- make production promotion traceable
Rules:
- merge only after acceptance and release checks
- create a version tag immediately after the release merge
### `hotfix/*` -> `release`
Preferred strategy:
- normal merge commit
Rules:
- branch must be narrowly scoped to the production issue
- branch name should identify the production problem clearly
Examples:
- `hotfix/login-timeout-loop`
- `hotfix/admin-init-guard`
## 6. Tag Rules
Every formal production release on `release` must be tagged.
Recommended format:
- `v1.0.0`
- `v1.1.0`
- `v1.1.1`
Tag semantics:
- major: incompatible or structurally significant release
- minor: backward-compatible feature release
- patch: backward-compatible hotfix release
Rules:
- tags are created on `release`, not on `dev`
- a tag must point to the exact production release commit
- patch hotfixes on `release` should increment the patch version
## 7. Hotfix Back-Merge Rules
Every hotfix merged into `release` must be merged back into both `main` and `dev`.
Required follow-up path:
`hotfix/*` -> `release` -> `main` -> `dev`
Rules:
- do not assume the fix already exists elsewhere
- perform the back-merge as soon as the production fix is verified
- if conflicts occur, resolve them immediately and document the resolution in the pull request or release record
This rule prevents production fixes from being lost in later development cycles.
## 8. Branch Protection Recommendations
### Protect `release`
Recommended controls:
- no direct push
- pull request required
- at least one reviewer required
- status checks required
- tag creation restricted to release maintainers if platform settings allow
### Protect `main`
Recommended controls:
- no direct push
- pull request required
- at least one reviewer required
- regression or build checks required before merge
### Manage `dev`
Recommended controls:
- direct push discouraged
- pull request preferred
- team may allow limited direct push for maintainers during active integration windows
If direct push is temporarily allowed on `dev`, it should remain an exception rather than the default workflow.
## 9. Release Readiness Criteria
Before promoting `dev` to `main`, confirm:
- selected feature scope is complete
- known blockers are resolved or explicitly deferred
- affected tests pass
- acceptance scope is defined
Before promoting `main` to `release`, confirm:
- release checklist is complete
- production initialization, build, and smoke verification are complete
- rollback or remediation path is clear
- release tag has been prepared
Reference:
- [docs/guides/release-checklist.md](guides/release-checklist.md)
## 10. Standard Workflow Examples
### New feature
1. create `feature/<name>` from `dev`
2. develop and review against `dev`
3. merge into `dev`
4. when milestone scope is stable, squash merge selected scope from `dev` to `main`
5. run candidate validation on `main`
6. merge `main` into `release`
7. create production tag on `release`
### Production hotfix
1. create `hotfix/<name>` from `release`
2. fix and validate only the production issue
3. merge into `release`
4. tag patch version on `release`
5. back-merge the same fix into `main`
6. back-merge the same fix into `dev`
## 11. Current Repository Mapping
For the current CTMS repository, the intended meaning is:
- `dev`: ongoing development branch
- `main`: next candidate major version branch
- `release`: long-lived stable production branch
Current local workspace layout:
- primary repository: `/Users/zcc/MyCTMS/ctms-dev` on `dev`
- `main` worktree: `/Users/zcc/MyCTMS/ctms-dev/.worktrees/main`
- `release` worktree: `/Users/zcc/MyCTMS/ctms-dev/.worktrees/release`
Current remote default branch:
- `origin/HEAD` points to `origin/main`
If `dev` and `main` temporarily point to the same commit, that is acceptable as a transition state.
The governance target is not to keep them permanently identical. The target is:
- `dev` keeps detailed development history
- `main` keeps milestone-level release-candidate history
- `release` keeps production-approved history with tags
## 12. Non-Goals
This policy does not require:
- rewriting branch history to a single commit
- forcing `main` to always differ from `dev`
- maintaining a separate release branch per version unless future scale requires it
The policy prioritizes traceability, stable promotion, and predictable maintenance over artificially minimal history.