[ST] Git Convention

[ST] Git Convention v1.0

This document follows the [ST] Git Convention v1.0, based on Conventional Commits 1.0.0 and the internal Selective Release Flow. All rules apply prospectively from the adoption date. Existing branches and history remain unchanged.


Repository Profile

Every repository MUST declare its profile. Customize the values below to match the project:

production_branch: main
developing_branch: dev

integration_environments:
  - dev

optional_integration_environments:
  - sit
  - qa
  - demo

uat_environment: uat
optional_preprod_environment: preprod
release_branch_pattern: release/*

merge_strategy: merge-commit             # or squash
delivery_strategy: selective-release
artifact_promotion: immutable            # when supported by CI/CD

MUST means mandatory. SHOULD means recommended unless there is a justified exception. MAY means optional.

A Git branch is not the same thing as a deployment environment. Projects MAY retain permanent environment branches when infrastructure genuinely requires them, but the release scope MUST be defined by release metadata and the release/* candidate, not by assuming every environment branch represents the next Production release.

Concept Branch or Environment Purpose
Production baseline main Source of truth for Production releases
Integration testing dev environment / branch Combined testing of current development work
Optional integration gates sit, qa, demo, or project-defined targets Additional verification before release selection
UAT uat environment Final validation of the exact release candidate
Release candidate release/* Selected production scope for a named release
Production Production environment Runs the exact artifact approved on UAT

Only branches declared in the repository profile are part of that project's required workflow. When an optional branch is enabled, branch protection rules and CI branch rules MUST be updated to include it.

Setting Example Value
Merge strategy Merge commit or squash
Delivery strategy Selective release
Artifact promotion Immutable artifact promotion, when supported
CI platform GitHub Actions / GitLab CI / Bitbucket Pipelines
Required CI checks commitlint, lint, build, test, branch-rules

1. Branching and Selective Release Flow

1.1 Working branches and branch independence

All new standalone working branches MUST be created from main (the base branch).

main MUST represent the Production baseline and source of truth for Production releases.

main
├── feat/A
├── feat/B
├── fix/C
└── refactor/D

Creating a branch from main does not mean developers work directly on main. Changes still flow through Pull Requests and required checks.

Standalone working branches MUST represent independently releasable changes whenever technically possible.

A working branch MUST NOT depend implicitly on code that exists only in:

  • dev
  • staging
  • uat
  • sit
  • qa
  • preprod
  • another environment branch

Environment branches MUST NOT be used as source-code dependency baselines. If a task depends on another unmerged task, that dependency MUST be explicit and handled through the dependency workflow in §1.4.

Exception: when multiple people work on the same epic and the task depends on shared epic code, task branches MUST be created from the shared epic/* branch as described in §1.5.

Format:

<type>/<ticket-id>-<short-description>

If there is no tracked ticket:

<type>/<short-description>

Approved branch types:

Type Use
feat/ New feature
fix/ Bug fix
refactor/ Code restructuring
chore/ Maintenance, tooling, dependencies
docs/ Documentation-only
hotfix/ Production emergency fix
epic/ Scoped shared baseline for dependent work
release/ Named Production release candidate

epic/ is a project-specific branch type for coupled work spanning multiple PRs. When a feature is small enough for a single PR, prefer feat/. task/ branches are not used going forward; use feat/ or chore/ instead.

Examples:

feat/PROJ-123-google-login
fix/PROJ-245-payment-timeout
refactor/PROJ-310-auth-service
chore/update-node-version
docs/api-authentication
epic/PROJ-100-aquaculture-analytics
release/1.5.0

Short description rules:

  • Use lowercase
  • Use - between words
  • Be concise and descriptive
  • Avoid developer names, dates, and vague names (test, new-code, update)

Working branches SHOULD be short-lived. Long-running working branches SHOULD synchronize with main regularly using the repository's merge or rebase policy. Shared branches MUST NOT be rebased unless the repository explicitly permits it.

git fetch origin
git merge origin/main

or, when permitted:

git fetch origin
git rebase origin/main

Before entering a release candidate, a working branch MUST be compatible with the selected release baseline.

1.2 Keep the working branch clean

A working branch MUST NOT merge environment branches into itself:

dev      --X--> feat/PROJ-123-google-login
staging  --X--> feat/PROJ-123-google-login
uat      --X--> feat/PROJ-123-google-login

The working branch MAY be synchronized with main when necessary. Task branches under an epic MAY synchronize with the shared epic/* branch instead.

A bug discovered while testing a feature SHOULD be fixed in that feature's source-of-truth working branch or epic source, not only in a temporary environment integration branch.

1.3 Developing environment

dev is an integration environment.

dev MAY contain multiple in-progress, completed, experimental, or independently releasable changes at the same time.

The contents of dev MUST NOT be interpreted as the contents of the next Production release.

A Production release candidate MUST NOT be created by blindly promoting the current state of dev.

DEV = A + B + C + D

A = ready
B = testing
C = bug found
D = still developing

The release process MUST support releasing a ready independent scope:

Release 1.5.0 = A

without requiring B, C, or D when they are independent.

DEV = integration state
UAT = release state

Feature-level testing MAY happen on DEV, SIT, QA, demo, or other configured integration environments. DEV answers: "Does this feature or change integrate correctly with current development work?"

1.4 Dependency management

Scrum/Jira manages dependency discovery, planning, ownership, and sequencing. The Git/release strategy manages how those dependencies are represented and safely integrated or released.

Dependencies between work items MUST be explicit.

A PR SHOULD expose technical and release dependencies clearly in its description, using a declaration such as:

Depends-On: PROJ-101

Example:

PROJ-101: Order History
    ^
    |
PROJ-102: Export Excel

PROJ-102 Depends-On: PROJ-101

If work item B depends on A and A is not already part of main, any release containing B MUST also contain A.

A release MUST contain the complete mandatory dependency closure of all selected work items.

C -> B -> A

Selecting C implies:

Release = A + B + C

unless A and/or B are already present in the Production baseline.

Feature flags SHOULD be considered when incomplete or controlled functionality can safely coexist with Production code. A disabled feature MUST NOT alter existing Production behavior. Feature flags MUST NOT be used as a substitute for declaring mandatory technical dependencies.

1.5 Epic collaboration workflow

Use an epic/* shared branch when multiple people need to deliver separate tasks that only work correctly when combined.

epic/* is not an environment branch, not a global replacement for dev, and not a way to force unrelated features to share a baseline. It is a scoped shared baseline for genuinely dependent work.

Independent work SHOULD branch directly from main. Dependent work SHOULD use explicit dependency declarations and an epic/* or stacked branch when appropriate.

main
 |
 +-- epic/order-history
       |
       +-- feat/PROJ-101-order-history
       +-- feat/PROJ-102-export-excel

Create an epic branch from main:

git fetch origin
git switch main
git pull origin main

git switch -c epic/PROJ-100-aquaculture-analytics
git push -u origin epic/PROJ-100-aquaculture-analytics

Task branches that depend on the epic code MUST branch from the epic branch:

git fetch origin
git switch epic/PROJ-100-aquaculture-analytics
git pull origin epic/PROJ-100-aquaculture-analytics

git switch -c feat/PROJ-123-pond-chart

Each task PR into the epic branch SHOULD pass CI and review. The epic owner is responsible for confirming that the combined code still builds and the feature can run end-to-end.

When the epic has enough code for integration testing, open a PR from the epic branch or a temporary epic integration branch to dev or another configured integration target. When selected for a Production release, the epic branch, or the selected changes from it, MUST be included in release/* with its dependency closure.

1.6 Environment PRs and temporary integration branches

Code destined for dev or optional integration environments such as sit, qa, demo, or preprod MAY use either a direct PR or a temporary integration branch.

Use a direct PR from the original working branch or epic branch when:

  • The branch can merge into the destination without conflicts
  • No environment branch has been merged into the source branch
  • The change can be verified safely from the source branch

Use a temporary integration branch when:

  • The PR has conflicts with the destination integration branch
  • The team needs to test the change combined with the latest integration branch before merge
  • The destination already contains code that is not in main and MUST NOT be pulled into the source branch
  • A previous integration branch to the same environment was already merged and another integration branch is needed

Environment branches MUST NOT be merged into the original working branch or epic branch. Resolve environment conflicts only on the temporary integration branch.

Format:

<source-branch>-<destination>
<source-branch>-<destination>-r<number>

Examples:

feat/PROJ-123-google-login-dev
feat/PROJ-123-google-login-sit
feat/PROJ-123-google-login-qa
feat/PROJ-123-google-login-preprod
feat/PROJ-123-google-login-dev-r2
epic/PROJ-100-aquaculture-analytics-dev

Direct PR flow when clean:

PR: feat/PROJ-123-google-login -> dev
PR: epic/PROJ-100-aquaculture-analytics -> dev

Integration branch flow when needed:

git fetch origin

git switch feat/PROJ-123-google-login
git switch -c feat/PROJ-123-google-login-dev

git merge origin/dev
# Resolve conflicts here, not on the working branch
# Run build / lint / tests

git push -u origin feat/PROJ-123-google-login-dev

Then open a PR: feat/PROJ-123-google-login-dev -> dev.

Merged working and temporary integration branches MAY be deleted after their associated Pull Requests are merged and traceability is preserved.

Audit history MUST rely primarily on Git commits, Pull Requests, release tags, release manifests, and deployment records. Permanent retention of temporary branches MUST NOT be the primary audit mechanism.

1.7 Release branches and release selection

Normal Production releases using the Selective Release Flow MUST use a release candidate:

release/<version>

Examples:

release/1.5.0
release/2.0.0
release/2026.09.1

A release branch MUST start from the intended Production baseline (main) and contain only:

  • Selected approved changes
  • Mandatory dependencies of those changes
  • Release-specific fixes when required

Teams MUST NOT assume everything currently present on DEV belongs in the release.

A release/<version> branch MUST record the exact Production base commit from which it was created. Before final UAT begins, the release scope and release baseline MUST be frozen.

The frozen release candidate consists of:

base Production commit
+
selected changes
+
mandatory dependency closure
+
approved release-specific fixes

Example:

main@abc123
    |
    + A
    + C
    + dependency D
    |
    v
release/1.5.0@def456

The exact release/1.5.0@def456 state MUST be built and submitted to UAT.

feat/A -----\
feat/B ------+--> DEV
feat/C -----/

Release selection: A + C

main
 |
 +--> release/1.5.0
        + A
        + C
          |
          v
         UAT

Normal versioned/selective Production release flow:

working branches
      |
      v
     DEV
integration testing
      |
      | release selection
      v
release/x.y.z
      |
      v
     UAT
exact release candidate
      |
      v
    main
      |
      v
    PROD

Direct working-branch -> main MAY be used only when the repository explicitly uses a single-change release model and still guarantees exact release-candidate verification. hotfix/* -> main remains valid for Production incidents.

A single-change release exception MUST still guarantee exact candidate verification, immutable artifact identity where supported, dependency validation, UAT/release approval, and auditability.

Conflicts discovered while composing a release MUST be resolved on the release candidate or on an appropriate source-of-truth branch. A conflict resolution that changes runtime behavior MUST be treated as a release change. The resulting combined release candidate MUST pass CI and UAT as a whole; successful DEV testing of individual changes is not sufficient evidence that a newly resolved release candidate is safe.

compose release
      |
      v
resolve conflicts
      |
      v
build
      |
      v
CI / integration tests
      |
      v
UAT

1.8 Release manifest and ownership

Every Production release MUST have a Release Owner or equivalent accountable role. The role MAY be performed by a Tech Lead, DevOps engineer, Release Manager, or another project-defined owner.

For every Production release, the Release Owner MUST verify:

  • Release scope
  • Included work
  • Dependencies
  • Release manifest
  • CI status
  • UAT approval
  • Artifact identity
  • Release baseline
  • Migration compatibility
  • Production promotion
  • Rollback readiness

Every Production release MUST have auditable release metadata. This MAY be represented by a release manifest, Release PR description, CI metadata, or an equivalent mechanism.

The release metadata MUST identify at least:

  • Release version
  • Base branch and base commit
  • Included tickets or features
  • Required dependencies
  • Release commit SHA
  • Resulting build artifact
  • UAT approval/status
  • Migration metadata, when applicable
  • Production baseline at approval
  • Rollback or roll-forward strategy

Recommended example:

release: 1.5.0

base:
  branch: main
  commit: abc123

included:
  - PROJ-101
  - PROJ-105

dependencies:
  PROJ-105:
    - PROJ-101

migrations:
  - id: 20260915_add_user_phone
    backward_compatible: true
    reversible: true

excluded:
  - PROJ-110
  - PROJ-115

release_commit: def456

artifact:
  id: app:1.5.0-def456

uat:
  artifact: app:1.5.0-def456
  status: approved

rollback:
  previous_artifact: app:1.4.2-xyz789
  database_strategy: none-required

production_baseline_at_approval: abc123

excluded MAY be omitted when the release process already makes exclusions obvious.

The exact schema MAY remain project-specific, but equivalent information MUST be auditable where applicable. The release manifest MUST NOT rely on the contents of DEV as the definition of the release.

A completed release SHOULD be tagged from the exact release commit, for example release/1.5.0 -> tag v1.5.0.

1.9 UAT and immutable artifact promotion

Final UAT for a Production release MUST validate the complete release candidate, not isolated feature branches.

UAT answers: "Is this exact combination safe to release to Production?"

Any change to the release source state after final UAT begins MUST invalidate the previous UAT approval. This includes adding or removing a feature, adding or changing a dependency, merging a new main state, cherry-picking another commit, resolving a conflict in a way that changes source, fixing a UAT bug, changing a database migration, or changing release configuration that affects runtime behavior.

The changed release candidate MUST produce a new immutable artifact and MUST complete the required UAT validation again. Production MUST NOT receive a changed artifact using approval granted for an earlier artifact.

For deployable applications where CI/CD supports immutable artifacts, the artifact approved in UAT MUST be the same immutable artifact promoted to Production.

release/1.5.0
      |
     BUILD
      |
      v
app:1.5.0-<commit-sha>
      |
      +----> UAT
      |
      +----> PROD

This model MUST NOT be used when rebuilding could produce a different artifact:

release -> build -> UAT

main -> rebuild -> PROD

Production MUST NOT rebuild from a different source state after UAT approval. Artifact identity MUST be recorded in deployment or release metadata.

If a bug is discovered on UAT for release/x.y.z:

  1. Identify the owning working branch/change
  2. Apply the durable fix to the correct source-of-truth branch when still active
  3. Ensure the fix is included in release/x.y.z
  4. Rebuild a new immutable release artifact
  5. Redeploy that new artifact to UAT
  6. Invalidate the previous UAT approval
  7. Promote only the newly approved artifact to Production

UAT MUST NOT be patched manually.

Production promotion MUST verify the exact release commit, exact immutable artifact, valid UAT approval for that artifact, current Production baseline, dependency closure, migration compatibility, and rollback/roll-forward readiness. If any of these changed after approval, Production promotion MUST stop.

1.10 Database migration and backward compatibility

Selective release MUST account for database and schema dependencies.

Every release containing a database migration MUST document:

  • Migration identifier
  • Affected service/application
  • Whether the migration is backward compatible
  • Whether old application versions can operate after migration
  • Rollback impact
  • Data migration impact
  • Whether the migration is reversible
  • Required deployment ordering

A release containing an incompatible migration MUST NOT be promoted until its deployment and rollback strategy has been explicitly reviewed.

Destructive database migrations SHOULD use an expand-and-contract strategy. Schema changes SHOULD remain backward compatible for at least the deployment and rollback window when technically feasible.

Release N - Expand
ADD COLUMN new_name
application supports old_name + new_name

Release N+1 - Migrate
backfill old_name -> new_name
application primarily uses new_name

Release N+2 - Contract
remove old_name

Database changes MUST participate in dependency management.

PROJ-101 Database schema change
        |
        v
PROJ-102 Backend API
        |
        v
PROJ-103 Frontend

PROJ-102 Depends-On: PROJ-101
PROJ-103 Depends-On: PROJ-102

Selecting PROJ-103 requires PROJ-101 + PROJ-102 + PROJ-103 unless the dependencies are already satisfied by main / Production. CI or Release Owner validation MUST consider migrations when validating dependency closure.

1.11 Production rollback

Every Production release MUST define a rollback or roll-forward strategy before deployment.

When immutable artifacts are available, rollback SHOULD promote the previously approved Production artifact instead of rebuilding an older Git revision.

Production artifact v1.4
        |
        v
deploy artifact v1.5
        |
        v
problem detected
        |
        v
rollback to artifact v1.4

When immutable artifacts are available, normal rollback MUST NOT be defined as checking out an old Git commit, rebuilding, and deploying, because the rebuilt artifact may not be identical to the previously known-good Production artifact.

Application rollback MUST NOT assume that database changes or external side effects are automatically reversible.

Application rollback != Database rollback != External side-effect rollback

The Release Owner MUST evaluate irreversible effects before Production deployment, including database migrations, deleted data, payment transactions, sent emails/messages, events published to external systems, object/file transformations, and third-party API actions.

When rollback of a database migration is unsafe, the release MUST document an alternative recovery strategy such as roll forward, data repair, compatibility deployment, or feature disablement.

When rollback is unsafe because of database state, external side effects, or compatibility constraints, the release MAY use a roll-forward recovery strategy. The selected recovery strategy MUST be documented before or during the incident and remain auditable.

v1.5 deployed
     |
     v
database already migrated
     |
     v
rollback unsafe
     |
     v
hotfix/1.5.1
     |
     v
roll forward

1.12 Concurrent releases

The standard MUST support multiple active release lines.

main@A
 |
 +-- release/1.5
 |      |
 |      +--> UAT
 |
 +-- release/1.6
        |
        +--> preparation

Every active release MUST declare its Production base commit.

release: 1.5.0
base_commit: abc123

When main advances while another release branch remains active, the Release Owner of the active release MUST evaluate whether synchronization with the new Production baseline is required. Active release branches MUST NOT automatically merge or rebase the latest main.

If the new Production changes are not required, the release baseline MAY remain unchanged and the decision MUST be documented. If the changes are required, the smallest safe synchronization SHOULD be used; the candidate state changes, a new artifact MUST be built, and UAT approval MUST be completed again.

After a hotfix reaches Production, the Release Owner MUST evaluate every active release branch that could reintroduce the defect. Affected releases MUST include the hotfix or another durable correction and complete a new candidate build and UAT cycle. Unaffected releases MUST document the decision. Teams MUST NOT blindly merge the complete current main into every release branch.

Before Production promotion, CI/CD MUST verify that the release is based on an allowed Production lineage and will not unintentionally replace a newer Production state. Out-of-order Production releases MUST require an explicit exception and impact review. Where this cannot be automated, the Release Owner MUST perform and record the verification.

1.13 Release invariants

The following MUST always be true for a normal Production release:

  1. Release scope is explicit.
  2. Release dependencies are complete.
  3. Release baseline is known.
  4. UAT validates the complete release candidate.
  5. UAT approval is bound to an exact artifact/source state.
  6. Any candidate mutation invalidates previous approval.
  7. Production receives the exact approved immutable artifact.
  8. Database compatibility has been evaluated.
  9. Rollback or roll-forward strategy is known.
  10. Concurrent release lines cannot silently overwrite newer Production state.

These invariants are more important than the exact Git commands used to implement them.

1.14 Protected branches

The following branches, when present, MUST be protected:

main
release/*
dev
sit
qa
demo
uat
preprod / pre-prod
  • Direct pushes MUST NOT be used in normal development
  • Changes MUST go through an approved Pull Request with passing CI checks
  • Exception: explicitly defined emergency incident process (see §4.3)

1.15 Allowed PR routes

Every project MUST define which source branches may target each protected or shared branch. The matrix below is the default for selective release.

Target branch Allowed source branches Purpose
epic/* Task branches created from the epic branch, such as feat/*, fix/*, refactor/*, docs/*, chore/* Combine dependent work for a multi-person epic
dev Original working or epic branches when clean, or integration branches ending in -dev / -dev-r<number> Integration testing; not release definition
sit Original working or epic branches when clean, or integration branches ending in -sit / -sit-r<number> Optional integration verification
qa Original working or epic branches when clean, or integration branches ending in -qa / -qa-r<number> Optional QA verification
demo Original working or epic branches when clean, or integration branches ending in -demo / -demo-r<number> Optional demo verification
preprod / pre-prod release/*, or original working/epic branches when configured as an integration target Optional production-like verification
release/* Selected original working branches, epic/*, dependency branches, or release-specific fix/* branches Compose exact Production candidate
uat release/* only for final Production UAT, unless the repository explicitly documents a non-production UAT use Validate exact release candidate
main release/* or hotfix/*; original working branches only for explicitly documented single-change release repositories Production release

The normal Production release path MUST NOT be feat/* -> dev -> uat -> main.

1.16 Task, feature, and bug implementation workflow

Use this flow for normal implementation work: new features, product tasks, non-production bug fixes, refactors, documentation, and chores.

  1. Confirm scope, ticket reference, acceptance criteria, dependency declarations, migration/deployment notes, feature flags, and verification needs.
  2. Create one original working branch from main, or from epic/* when the work genuinely depends on shared epic code.
  3. Implement on the original working branch using Conventional Commits and project-required tests.
  4. Open a PR to dev or another configured integration target when integration testing is needed. Use a temporary integration branch only when conflicts or combined-environment verification require it.
  5. Fix bugs found during integration testing in the source-of-truth working branch or epic source, then re-open a direct PR or retry integration PR to the failed target.
  6. When the work is approved for a Production release, include it and its mandatory dependency closure in release/<version>.
  7. Build the immutable artifact from the release candidate.
  8. Deploy that artifact to UAT for final release-candidate validation.
  9. After UAT approval, merge release/<version> to main and promote the same approved artifact to Production.
  10. Merge main back into dev and active long-lived branches when needed to keep future integration work aligned with Production.

Summary diagram:

main
├── feat/A ──────┐
├── feat/B ──────┼──> DEV
├── feat/C ──────┘
└── epic/X ──────────> DEV


              RELEASE SELECTION
                     |
                  A + C
                     |
                     v
             release/1.5.0
                     |
              freeze candidate
                     |
                     v
                    CI
                     |
                     v
                   BUILD
                     |
                     v
            immutable artifact X
                     |
                     v
                    UAT
                     |
             approve artifact X
                     |
                     v
        verify Production baseline
                     |
                     v
            release/1.5.0 -> main
                     |
                     v
        promote SAME artifact X
                     |
                     v
                   PROD
                     |
             +-------+-------+
             |               |
          success          failure
             |               |
             v               v
          tag/release   rollback previous
                       approved artifact
                            OR
                       controlled roll-forward
DEV  = integration state
UAT  = exact release candidate
PROD = exact approved artifact

2. Commit Convention

All commits that become part of protected-branch history MUST follow Conventional Commits 1.0.0.

2.1 Format

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

2.2 Approved commit types

Type Use
feat New user-facing or system capability
fix Bug fix
refactor Code restructuring without behavior change
perf Performance improvement
docs Documentation-only change
test Test-only change
build Build system, dependencies, build configuration
ci CI/CD pipeline or automation
chore Maintenance not better represented by another type
style Formatting, whitespace, code-style-only change
revert Reverting earlier changes

2.3 Scope

Optional. When used, scope MUST be a noun describing a section of the codebase.

Each project SHOULD define its own scope registry in its repository documentation (e.g. in this file or in a commitlint.config.js). Scopes SHOULD reflect the project's domain and architecture.

Example scope registry (adapt to your project):

auth        users       orders      payments
api         web         mobile      docker
k8s         database    ci

Good:

feat(auth): add Google OAuth login
fix(sensors): correct reading timestamp
ci(github): add staging deployment workflow

Avoid — ticket IDs or developer names in scope:

feat(PROJ-123): add Google OAuth login    ← don't
feat(hai): add Google OAuth login          ← don't

Use footer for ticket references instead:

feat(auth): add Google OAuth login

Refs: PROJ-123

2.4 Description rules

  • Be concise and specific
  • Describe what changed
  • Use consistent English
  • Begin with lowercase (unless proper noun)
  • No trailing period
  • Avoid vague messages: update code, fix bug, changes

Good:

fix(payment): handle gateway timeout
feat(ponds): add bulk water parameter import

Poor:

fix: bug fixed
feat: update code

2.5 Body and footer

The body MAY explain why the change was made or important context:

fix(alerts): prevent duplicate alert notifications

Ignore subsequent alert triggers while the previous notification
is still being delivered to avoid flooding the user.

Refs: PROJ-245

When a change is associated with a tracked work item, include a ticket reference in a footer:

Refs: PROJ-245

2.6 Breaking changes

Breaking changes MUST be marked with ! or a BREAKING CHANGE: footer:

feat(api)!: change authentication response format

or:

feat(api): change authentication response format

BREAKING CHANGE: authentication tokens are now returned inside the data object.

2.7 Development commits

During local development, temporary/WIP commits are fine:

wip login
try oauth
fix test

However, all commits entering protected-branch history MUST follow Conventional Commits.


3. Pull Request Standard

3.1 Requirements

  • Changes to protected branches MUST go through a Pull Request
  • The PR author MUST NOT be the only approver
  • All required CI checks MUST pass before merge
  • All blocking review comments MUST be resolved before merge

3.2 PR title

Since the repository uses merge commits, the PR title SHOULD follow Conventional Commit syntax for consistency:

feat(auth): add Google OAuth login [PROJ-123]

3.3 PR description

Use the repository PR template. Every non-trivial PR SHOULD include:

  • Ticket reference
  • What — brief summary
  • Why — motivation
  • Changes — list of changes
  • DependenciesDepends-On: PROJ-101, when applicable
  • Verification — testing checklist
  • Breaking Change — yes/no
  • Migration / Deployment Notes — if applicable

For Jira task tracking and OPS workflow rules, including status flow, release readiness, deployment, production verification, and incident handling, see ST Jira-OPS Convention.

3.4 Review

Reviewers SHOULD verify at least:

  • Correctness and expected behavior
  • Security and data-handling implications
  • Backward compatibility
  • Tests
  • Migration/deployment impact
  • Maintainability

3.5 Merge strategy

This repository uses merge commit as the default merge strategy.

All individual commits entering protected branch history MUST follow Conventional Commits format.


4. Bug Fix and Hotfix

4.1 Bugs found during integration or UAT

When a bug is found during DEV, SIT, QA, demo, or another integration target:

  1. Record the failed case in the ticket or PR comment
  2. Switch back to the source-of-truth working branch or epic source
  3. Implement the durable fix there
  4. Add or update tests when the bug is reproducible in automated tests
  5. Push the source branch
  6. Open a direct PR back to the failed integration target if the merge is clean
  7. Create a new retry integration branch only when conflicts or separate verification require it
  8. Resolve environment conflicts on the retry integration branch, when used
  9. Pass CI checks again
  10. Re-verify the failed integration target

Use retry suffixes when a new temporary integration branch is needed:

feat/PROJ-123-google-login-dev-r2
feat/PROJ-123-google-login-sit-r2
feat/PROJ-123-google-login-qa-r2
feat/PROJ-123-google-login-preprod-r2

Flow:

QA finds bug on DEV
        |
feat/PROJ-123-google-login          <- fix here
        |
feat/PROJ-123-google-login          <- direct PR if clean
        |
feat/PROJ-123-google-login-dev-r2   <- retry integration branch if needed
        |
dev                                  <- PR merge
        |
QA re-verifies

The fix MUST NOT exist only on the temporary integration branch. That can lose the fix when the release candidate is composed.

If a bug is discovered on UAT for release/x.y.z, the previous UAT approval MUST be invalidated. The durable fix MUST be included in release/x.y.z, a new immutable artifact MUST be built and redeployed to UAT, and Production MUST receive only the newly approved artifact.

If the bug is a new standalone issue unrelated to an active task branch, create a new fix/ working branch from main and follow the implementation workflow in §1.16.

4.2 Hotfix (production defect)

A hotfix is for a production defect requiring expedited correction.

A hotfix branch MUST be created from the production/base branch.

Branch format:

hotfix/<ticket-id>-<short-description>

Hotfix steps

  1. Confirm severity, owner, rollback plan, and affected production version
  2. Create the hotfix branch from the latest main
  3. Implement the smallest safe fix required to resolve the production defect
  4. Add or update regression tests when possible
  5. Run the required checks locally
  6. Push the hotfix branch and open a PR to main
  7. Get required review and CI approval
  8. Merge to main
  9. Deploy or trigger the production deployment process
  10. Verify production after deployment
  11. Evaluate active release/*, dev, and long-lived epic/integration lines that could reintroduce the defect, and synchronize the hotfix only where required
git fetch origin
git switch main
git pull origin main

git switch -c hotfix/PROJ-900-payment-crash
# Apply the fix
git add .
git commit -m "fix(payments): prevent payment crash"
git push -u origin hotfix/PROJ-900-payment-crash
# Open PR: hotfix/PROJ-900-payment-crash -> main

Flow:

main
  │
  └── hotfix/PROJ-900-payment-crash
            │
            ├── CI / review
            │
            └── PR → main → production

Hotfix sync back to development

After the hotfix is merged to main, the Release Owner MUST evaluate active release/*, dev, and long-lived epic/integration lines that could otherwise reintroduce the defect. The hotfix MUST be synchronized only where required.

Option A — Merge main into dev (preferred when dev is not diverged significantly):

git fetch origin
git switch dev
git merge origin/main
# Resolve any conflicts
git push origin dev

Option B — Cherry-pick (when main has changes not yet intended for dev):

git fetch origin
git switch dev
git cherry-pick <hotfix-commit-sha>
# Resolve any conflicts
git push origin dev

Option C — Integration branch (when conflicts are expected or review is required):

git fetch origin
git switch -c hotfix/PROJ-900-payment-crash-dev origin/main
git merge origin/dev
# Resolve conflicts
git push -u origin hotfix/PROJ-900-payment-crash-dev
# Open PR: hotfix/PROJ-900-payment-crash-dev → dev

Regardless of method, the sync MUST happen promptly to avoid the defect reappearing in a future release. Teams MUST NOT blindly merge unrelated Production changes into branches when a targeted synchronization is safer.

4.3 Emergency path

In an emergency:

  • The production change MUST remain auditable
  • CI checks SHOULD still run where feasible
  • The hotfix MUST be synchronized back into active branches that could reintroduce the defect
  • Any skipped review MUST be completed post-incident

5. CI Enforcement

5.1 Minimum checks

Every repository MUST define mandatory CI checks appropriate to the project. At minimum:

Check Requirement
Conventional Commit validation MUST
Required project tests/checks MUST
Protected branch policy MUST
Required review/approval MUST

Where applicable, projects SHOULD also enforce:

  • Build
  • Lint
  • Unit tests
  • Integration tests
  • Type checking
  • Security/dependency scanning
  • Migration validation

5.2 Commit/PR validation

For repositories using merge commits:

all commits entering protected history -> Conventional Commit validation

For repositories using squash merge:

PR title / final squash message -> Conventional Commit validation

5.3 Release validation

Projects using selective releases MUST enforce release validation.

Validation SHOULD be automated in CI/CD where technically feasible.

Recommended checks include:

  • Release composition validation
  • Dependency closure validation
  • Release baseline validation
  • Release lineage validation
  • Release candidate mutation validation
  • Release branch policy validation
  • Artifact identity validation
  • UAT approval/artifact match validation
  • Migration metadata validation
  • Production baseline compatibility validation

When the repository has automated dependency metadata available, CI MUST validate that every release/* branch contains the complete mandatory dependency closure for the selected work. Until a validation can be automated, the Release Owner MUST perform the equivalent manual verification and record the result in release metadata.

Invalid release example:

Dependencies:

D -> B
B -> A

Release = A + C + D

The release is invalid because B is missing. CI SHOULD report the failure in a form equivalent to:

Release validation failed:

PROJ-D requires PROJ-B.
PROJ-B is neither present in the Production baseline
nor included in this release.

Valid release:

Release = A + B + C + D

For deployable applications with immutable artifact support, CI/CD MUST record the build artifact identity and make it traceable from UAT approval through Production promotion.

Conceptual release gate:

release/*
    |
    v
composition check
    |
    v
dependency check
    |
    v
migration check
    |
    v
BUILD
    |
    v
immutable artifact
    |
    v
UAT
    |
    v
approval binding
    |
    v
Production baseline check
    |
    v
PROD

5.4 Recommended tooling

Repositories MAY use tools such as:

  • commitlint + @commitlint/config-conventional
  • Husky / lefthook (local hooks)
  • GitHub Actions / GitLab CI / Bitbucket Pipelines
  • Branch protection rules
  • CODEOWNERS
  • semantic-release / standard-version

Local Git hooks MAY provide fast developer feedback, but local hooks MUST NOT be the only enforcement mechanism. Server-side CI MUST be the source of truth.

6. Migration Notes

6.1 No history rewrite

Existing Git history MUST NOT be rewritten to comply with this standard. The standard applies prospectively from the adoption date.

6.2 Legacy branches

Existing branches created before the adoption date MAY finish under their current names. New branches MUST follow the naming convention.

6.3 Migration checklist

Before enforcement is enabled, each project owner/Tech Lead MUST confirm:

[ ] Production/base branch is documented
[ ] Developing integration target is documented
[ ] Optional integration environments are documented, if used
[ ] UAT environment and release-candidate validation process are documented
[ ] Release branch pattern is documented
[ ] Delivery strategy is selective-release, or project exception is documented
[ ] Artifact promotion strategy is documented
[ ] Release freeze and candidate mutation rules are documented
[ ] Migration compatibility metadata is documented, if applicable
[ ] Rollback or roll-forward strategy is documented
[ ] Concurrent release lineage verification is documented
[ ] Merge strategy is documented
[ ] Protected branches are configured
[ ] Branch protection and CI branch rules match the declared branches
[ ] Required approvals are configured
[ ] Required CI checks are configured
[ ] Conventional Commit validation is configured
[ ] Dependency declaration and release manifest process are documented
[ ] Jira workflow and required statuses are documented
[ ] OPS deployment readiness and incident paths are documented
[ ] Project-specific scopes/types are documented (if needed)
[ ] PR template is added
[ ] Hotfix path is documented
[ ] Adoption date is communicated

6.4 Recommended rollout

Existing projects SHOULD roll out the standard gradually:

  1. Phase 1 — Document: Publish standard, repository-specific branch mapping, and PR template.
  2. Phase 2 — Warn: Run commit/PR/branch checks in warning mode. Fix unclear rules before blocking.
  3. Phase 3 — Enforce: Enable protected branches, mandatory CI, required reviews, and Conventional Commit validation.
  4. Phase 4 — Automate: Add changelog generation, release notes, semantic versioning, release composition validation, dependency closure validation, and immutable artifact promotion.

Quick Reference

Branch

feat/PROJ-123-google-login          <- independent working branch from main
fix/PROJ-245-payment-timeout        <- independent bug fix branch from main
feat/PROJ-123-google-login-dev      <- temporary integration branch -> dev, if needed
epic/PROJ-100-aquaculture-analytics <- scoped shared baseline for dependent work
release/1.5.0                       <- exact Production release candidate
hotfix/PROJ-900-payment-crash       <- emergency Production fix from main

Commit

feat(auth): add Google OAuth login

Refs: PROJ-123
Depends-On: PROJ-101

Selective release flow

main
├── feat/A ──────┐
├── feat/B ──────┼──> DEV
├── feat/C ──────┘
└── epic/X ──────────> DEV


              RELEASE SELECTION
                     |
                  A + C
                     |
                     v
             release/1.5.0
                     |
              freeze candidate
                     |
                     v
                    CI
                     |
                     v
                   BUILD
                     |
                     v
            immutable artifact X
                     |
                     v
                    UAT
                     |
             approve artifact X
                     |
                     v
        verify Production baseline
                     |
                     v
            release/1.5.0 -> main
                     |
                     v
        promote SAME artifact X
                     |
                     v
                   PROD
                     |
             +-------+-------+
             |               |
          success          failure
             |               |
             v               v
          tag/release   rollback previous
                       approved artifact
                            OR
                       controlled roll-forward
DEV  = integration state
UAT  = exact release candidate
PROD = exact approved artifact

Bug fix flow

bug found in DEV/integration target -> fix source-of-truth working branch or epic -> direct PR when clean or retry integration branch (-r2) -> re-test
bug found in UAT -> fix source branch -> update release/* -> rebuild artifact -> UAT re-approval -> same artifact to PROD

Hotfix flow

main -> hotfix/* -> review + CI -> main -> production deploy -> verify production -> evaluate active release/dev/epic lines -> sync only where required