9.6 KiB
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
mainreadable as the next major version baseline - keep
releasestable 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
devin 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
devtomain - approved release scope is promoted from
maintorelease
Direct promotion that skips stages is discouraged and must be justified in writing.
3.1 Unified Web and Desktop Mainline
CTMS Web and Desktop are two delivery targets of the same product version. They share the Vue application, API contract, and product branches.
Rules:
- Do not create long-lived
web-dev,desktop-dev,web-release, ordesktop-releasebranches. - Web and Desktop changes both follow
feature/*->dev->main->release. - A platform-specific feature branch is allowed while work is in progress, for
example
feature/desktop-file-picker, but it must merge back intodev. codex/ctms-desktopis a temporary desktop integration branch. After the Tauri baseline is accepted intodev, new desktop work must use short-lived feature branches from the currentdev.- Platform differences belong behind
frontend/src/runtime/. Shared business modules must not import Tauri APIs directly. - A release tag identifies one product source state. Web and Desktop artifacts for that release must be built from the same tag and Git commit.
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
mainat a version or milestone granularity - avoid making
maina duplicate ofdevcommit-for-commit
Rules:
- each merge to
mainshould 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 candidaterelease(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-loophotfix/admin-init-guard
6. Tag Rules
Every formal production release on release must be tagged.
Recommended format:
v1.0.0v1.1.0v1.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 ondev - a tag must point to the exact production release commit
- patch hotfixes on
releaseshould increment the patch version - Web and Desktop use the same semantic version. Do not add a separate Desktop product version.
- Desktop packaging-only rebuilds may add build metadata to the artifact name, but must retain the product version and record the source commit.
- Before creating a tag, run
cd frontend && npm run version:check. - Change the shared client version with
cd frontend && npm run version:set -- <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:
10. Standard Workflow Examples
New feature
- create
feature/<name>fromdev - develop and review against
dev - merge into
dev - when milestone scope is stable, squash merge selected scope from
devtomain - run candidate validation on
main - merge
mainintorelease - create production tag on
release
Production hotfix
- create
hotfix/<name>fromrelease - fix and validate only the production issue
- merge into
release - tag patch version on
release - back-merge the same fix into
main - back-merge the same fix into
dev
11. Current Repository Mapping
For the current CTMS repository, the intended meaning is:
dev: ongoing development branchmain: next candidate major version branchrelease: long-lived stable production branch
Current local workspace layout:
- primary repository:
/Users/zcc/MyCTMS/ctms-devondev mainworktree:/Users/zcc/MyCTMS/ctms-dev/.worktrees/mainreleaseworktree:/Users/zcc/MyCTMS/ctms-dev/.worktrees/release
Current remote default branch:
origin/HEADpoints toorigin/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:
devkeeps detailed development historymainkeeps milestone-level release-candidate historyreleasekeeps production-approved history with tags
12. Non-Goals
This policy does not require:
- rewriting branch history to a single commit
- forcing
mainto always differ fromdev - 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.