Note on this document: this is the branching and release policy the
jira-sdlcskills (in../skills/) were written against — it's what "the default base branch," thefeature//hotfix/split, and the squash-merge-into-parent-then-manual-release logic all assume. It's already generic (no project names, no company specifics — reviewed before publishing this repo). If your process differs, adapt this document to match yours, then update<DEFAULT_BASE_BRANCH>in.jst/jira-sdlc-tools.envin the project root (see../skills/_shared/project-config.md) and the branch-prefix rules injira-task-assignerandjira-api-reference.md§12 to match.
Software Development Life Cycle (SDLC) & Branching Strategy
1. Overview and Purpose
This document defines the standard operating procedures for the Software Development Life Cycle (SDLC), Git branching strategy, and release management for this repository.
Audience: Human developers, DevOps engineers, and Autonomous AI/LLM coding assistants.
Core Philosophy:
- Continuous Integration / Batched Deployment: We merge code continuously to staging but release to production in scheduled two-week sprint batches.
- Decoupled Deployments: Deployment does not equal release. We rely heavily on Feature Flags to merge incomplete or untested features safely into production without exposing them to end-users.
2. Branch Architecture
| Branch Name Pattern | Protected? | Source | Merges To | Purpose |
|---|---|---|---|---|
main | ✅ Yes | release/*, hotfix/* | development | Represents the current production state. Strictly tagged with Semantic Versioning (e.g., v1.2.3). |
development | ✅ Yes | main | release/* | The default working branch. Represents Staging/Integration. Code here is continuously deployed to the staging environment. |
feature/ISSUE-KEY-slug | ❌ No | development | development | Used for new features and non-critical bug fixes. |
hotfix/ISSUE-KEY-slug | ❌ No | main | main & development | Used only for critical production bugs that cannot wait for the next sprint release. |
release/sprint-<X.Y.Z> | ❌ No | development | main | Temporary branch created at the end of a sprint for QA hardening and final bug fixes before production release. Named after the intended release version (computed from latest v* tag + chosen bump level, default minor — see §5). |
3. The 2-Week Sprint Lifecycle
Our development cycles run in 14-day sprints. The Git workflow strictly follows this cadence.
Phase 1: Active Development (Days 1 to 11)
- Developers branch off
developmentto createfeature/*branches. - Pull Requests (PRs) are opened against
development. - Once approved, PRs are merged immediately.
- Rule: If a feature is incomplete, it MUST be wrapped in a Feature Flag before merging into
development.
Phase 2: Feature Freeze & Release Cut (Day 12)
- A new release branch is cut from
development(e.g.,release/sprint-0.3.0). The branch name embeds the intended SemVer version —cut-release.ymlcomputes it from the latestv*tag + the chosen bump level (patch/minor/major, defaultminorper §5). The version lives in the branch name from this point on;release.ymlreads it back out at merge time (§5), so the way to change a release's version is to rename or re-cut the branch, not to relabel a PR. - No new features are allowed into this release branch.
developmentremains open for developers to start merging features for the next sprint.
Phase 3: QA & Hardening (Days 12 to 14)
- QA tests the
release/*branch in the staging environment. - If bugs are found, developers branch directly off the
release/*branch, fix the bug, and open a PR back into therelease/*branch.
Phase 4: Production Deployment (Day 14)
- The
release/*branch is merged intomainvia a PR. - A snapshot of the documentation is cut for that version (
docusaurus docs:version) and committed onmain, so the tagged commit carries the docs as that release published them. - A Semantic Version Tag (e.g.,
v0.95.4) is applied to that commit onmain. - The CI/CD pipeline deploys
mainto Production. - The documentation site is republished so the new version appears on it.
mainis merged back intodevelopmentto ensure all QA bug fixes are synced.- The
release/*branch is deleted.
All of the above is automated by release.yml (see
CI.md). The one exception is below.
Cutting the docs version by hand
release.yml runs from the version of itself that already exists on main, so
the release that first introduces the docs-versioning step cannot run it —
and the same applies to any release merged before that change reaches main.
That release ships without a docs snapshot unless somebody cuts one. Do it from
main immediately after the release, substituting the version that was just
tagged (no leading v):
git checkout main
git pull origin main
cd website
npm ci
npm run docusaurus -- docs:version 0.95.4
npm run build # snapshot-only breakage fails HERE, not in review
cd ..
git add website/versioned_docs website/versioned_sidebars website/versions.json
git commit -m "docs: version snapshot v0.95.4"
git push origin main
Two things to know while doing it:
- All three paths are committed. An ignored snapshot is a released version that silently is not on the site;
website/.gitignorecovers build products only. - That push will not republish the site on its own if it is made with a CI token — a
GITHUB_TOKENpush creates no workflow runs. Pushing it yourself from a laptop does triggerdocs.yml. If in doubt, dispatch it explicitly:gh workflow run "Docs site" --ref main.
4. Emergency Production Bug Flow (Hotfixes)
When a critical bug is discovered in production that cannot wait for the end of the 2-week sprint cycle, the Hotfix Flow is triggered. This process completely bypasses the development branch to ensure we do not accidentally deploy unreleased sprint features prematurely.
[main (v1.0.0)] ────► [hotfix/ISSUE-123] ────► [QA/Verification]
│ │
▼ ▼
[main (v1.0.1)] ◄─────────────────────────────────────┘ (Merge & Tag)
│
▼
[development] (Sync back immediately)
Step 1: Isolate and Branch
- Do NOT branch from
development. - Pull the latest code from
mainand create a hotfix branch:
git checkout main
git pull origin main
git checkout -b hotfix/ISSUE-KEY-short-description
Step 2: Fix and Validate
- Implement the fix locally.
- Deploy the hotfix branch to an isolated staging/preview environment for immediate QA validation.
Step 3: Production Merge and Patch Tagging
- Open a Pull Request targeting
main. - Once approved, merge the PR into
main. - Increment the PATCH version of your semantic tag (e.g.,
v1.2.4becomesv1.2.5). - The CI/CD pipeline triggers an automatic immediate deployment to Production.
Step 4: Downstream Synchronization (Crucial)
- To prevent the bug from being reintroduced during the next sprint release,
mainmust be merged back intodevelopmentimmediately following the production deployment.
git checkout development
git pull origin development
git merge main
git push origin development
5. Versioning Strategy (SemVer)
We strictly adhere to Semantic Versioning (vMAJOR.MINOR.PATCH) on the main branch.
The version for each release is taken from the branch name — no PR label is read:
- A
release/sprint-<X.Y.Z>branch carries its SemVer version in the name (set at cut time bycut-release.yml).release.ymlparses that version back out at merge time; a malformed name (anything other thanrelease/sprint-<X.Y.Z>, including a leadingv) fails the release. To ship a different version, rename or re-cut the branch. - A
hotfix/*branch always takes a patch bump on the latestv*tag. A hotfix is by §4's definition an emergency fix for a critical production bug — that IS a patch; work needing a minor or major bump belongs in arelease/*branch, where the version is explicit.
Commit-message conventions play no part in version resolution.
- MAJOR (
v2.0.0): Breaking changes, massive UI overhauls, or major architectural shifts. - MINOR (
v1.5.0): New sprint releases containing backward-compatible features (the standard increment for Day 14 releases — thecut-release.ymldefault). - PATCH (
v1.5.1): Emergencyhotfix/*branches merged directly tomainmid-sprint.
Note: Version tags must contain ONLY the semantic version number (e.g.,
v1.5.0), never sprint identifiers (e.g.,v1.5.0-sprint24), to ensure compatibility with standard package managers and CI tools.
6. Feature Flags
Scope note: Feature flags are a project practice the
jira-sdlcskills do not automate — they never create, wrap, or toggle a flag on their own (see §7 #3). The guidance below applies where a project adopts flags; adopting, wiring, or dropping them is a human/product decision.
To prevent merge conflicts and "branch rot", long-running feature branches are discouraged.
- All code should ideally be merged into
developmentwithin 3-4 days. - If a feature spans multiple sprints, it MUST be protected by a feature flag.
- The feature is deployed to production silently. The product team toggles the flag to
truewhen the feature is ready for public consumption.
7. 🤖 LLM System Directives
Instructions for AI coding assistants (Copilot, Cursor, Gemini, etc.) reading this document:
- Branch Naming: Work branched off
developmentis always namedfeature/<ISSUE-KEY>-<kebab-case-description>(e.g.git checkout -b feature/PROJ-123-add-user-auth) —feature/is the only branch type cut fromdevelopment, and it covers all planned work, features and bug fixes alike. The one exception is an emergencyhotfix/offmain(see #2); never create ahotfix/branch fromdevelopment. - Target Branches: Always default PR creation scripts or git merge targets to
development, unless explicitly told it is a production hotfix — those (and only those) branch frommain, are namedhotfix/<ISSUE-KEY>-<kebab-case-description>, and targetmain. - Feature Flags: Do not add feature-flag wrapping on your own initiative. Whether incomplete work ships behind a flag (§6) is a deliberate human/product decision — wrap an entry point in a flag only when the issue or the user explicitly asks for it, and then follow the codebase's existing flag pattern rather than inventing one.
- Commit Messages & Versioning: SemVer bumps are driven by the branch name (
release/sprint-<X.Y.Z>carries the version;hotfix/*is always a patch), not by PR labels or commit-message parsing — so Conventional Commits are not required. Prefix each commit with its Jira issue key (<ISSUE-KEY> <short imperative summary>, e.g.PROJ-123 add user auth) so history stays traceable to the issue;release.ymlresolves the version from the head ref on the merge (see §5).