# 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/` 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/` 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.