Files
ctms/docs/branch-governance.md
T
Cheng Zhou c23a5d6a22
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
build(desktop): allow controlled unsigned v0.1.0 release
2026-07-17 10:52:20 +08:00

10 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 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.

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, or desktop-release branches.
  • Web and Desktop changes both follow feature/* -> dev -> main -> release.
  • A platform-specific feature or agent task branch is allowed while work is in progress, for example feature/desktop-file-picker or codex/desktop-menu-polish, but it must merge back into dev.
  • codex/ctms-desktop was the temporary desktop integration branch for the Tauri baseline. It is no longer a current desktop mainline. Do not commit, rebase, or push new desktop work to it unless explicitly cleaning up the historical branch after its accepted changes are present on dev.
  • 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 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
  • 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
  • Desktop updater signatures are present and verified
  • platform signing is either complete or the exact version has an approved, checked-in exception in frontend/desktop-release-policy.json; the current v0.1.0 exception requires macOS ad-hoc signing, unsigned Windows artifacts, controlled distribution, and explicit trust warnings
  • rollback or remediation path is clear
  • release tag has been prepared

Platform signing remains the default for versions without an exact approved exception. An exception never permits disabling Tauri updater signatures or building Web, macOS, and Windows from different tags or commits.

Reference:

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.