Software Development Lifecycle
Sprint cycles and release cycles operate independently
Section titled “Sprint cycles and release cycles operate independently”Work is planned and executed in sprints that are staggered with releases (i.e. sprints don’t end with releases). By decoupling releases from sprint boundaries, we give ourselves space to build out test coverage without the pressure of “but we need to ship Thursday,” develop confidence in our QA process, and learn our actual cycle times without the noise of artificial deadlines.
Our current model is building the runway for CI/CD:
- Stabilize releases (where we are now): Establish a predictable release rhythm that doesn’t create panic. Use the breathing room to build comprehensive automated test coverage, make deployments low-risk and reversible, and develop QA processes that can keep pace with development.
- Shrink the gap: As test coverage grows and deployment confidence increases, the time needed between “code complete” and “released” naturally compresses. Releases start happening more frequently, not because we’re pushing harder, but because the safety nets are in place.
- Releases become non-events: Eventually, shipping is just something that happens—multiple times a day if needed—because automated tests catch regressions, rollbacks are trivial, and feature flags let us decouple deployment from exposure.
The question we should ask periodically: “What would need to be true for us to release more frequently without the panic?” The answer becomes our infrastructure and process roadmap.
Sprints
Section titled “Sprints”- Calendar-bound iterations of fixed duration
- Goal of a sprint cadence is to complete a defined chunk of work sized to fit within the sprint (i.e. the work is the variable)
- Each sprint concludes with a retrospective and sprint planning meeting
- Sprint boundaries are fixed regardless of work completion status
- Development targets releases one cycle ahead, allowing for better quality assurance and release preparation
- For the timing of the recurring sprint cycle, see the _Production Google calendar.
Release Milestones
Section titled “Release Milestones”- Goal of the release cadence is to ensure sufficient time for QA
- Milestone-based releases triggered by feature/goal completion
- Regular cadence but tied to milestone achievement rather than sprint end dates
- Releases may occur mid-sprint or span multiple sprints depending on milestone completion
Branches and Environments
Section titled “Branches and Environments”| Branch | Environment | Purpose |
|---|---|---|
main |
momentum-main.fly.dev | Source of truth for all code |
staging |
momentum-staging.fly.dev | Pre-release QA |
prod |
production | Live application |
All PRs merge to main. The staging and prod branches are deployment targets that are fast-forwarded to main (or to a release tag). They never receive independent commits directly. This means all three branches share the same commit history, eliminating divergence and making it always clear exactly what code is in each environment.
Release tags
Section titled “Release tags”Every release is tagged on main (e.g., v2.13.0). Because branches are fast-forwarded, the tag points to the same commit on all three branches. Tags serve as:
- The marker for what is currently in production
- The base for hotfix branches
- The boundary for “what’s queued for next release” (
git log v2.13.0..main)
Development Workflow
Section titled “Development Workflow”As a developer begins work on a ticket, they create a new git branch. They commit changes to their branch until the requirements in the ticket are met. Once complete, the developer creates a pull request against main.
Ticket Types
Section titled “Ticket Types”Tasks are managed as issues in Github.
| Type | Created by | Owned by | Closes ticket | Tagged to Milestone | Can belong to | Has PRs |
|---|---|---|---|---|---|---|
| Feature | Product | Product | Product | No | — | No |
| User Story | Product, QA | QA | QA | Yes | Feature | No |
| Task | Developers, QA | Developers | Developers | Yes | Feature, User Story, or another Task | Yes |
| Bug (P0-P3) | QA, Product, Developers | QA | QA | Yes | — | Yes |
Feature: A body of work, often spanning sprints. Features are containers for planning, not work items. Product closes them when the feature is complete, which may span multiple releases.
User Story: User-focused functionality that belongs to a Feature, or standalone for smaller user-facing changes. QA owns verification and closes these tickets.
Task: Technical work owned by developers. Tasks may be standalone or belong to a Feature, User Story, or another Task. A Task under another Task is a sub-task by relationship, not by type.
Bug (P0-P3): Unexpected problem or behavior. Priority is indicated by the type: P0 (Critical/Urgent), P1 (High), P2 (Medium), P3 (Low). QA verifies fixes and closes these tickets.
Every PR must be associated with a Task or Bug. This is a SOC2 requirement.
Labels
Section titled “Labels”Must Ship: Indicates the ticket must be included in the ticket’s Milestone.
Ticket Lifecycle
Section titled “Ticket Lifecycle”Tickets progress through the following states:
Triage
- Bike Rack / No status: Issue identified but not reviewed or scheduled.
- New: Newly filed ticket. Should be triaged.
Planning
- Sprint Backlog: Ticket can optionally be worked on during the current sprint. Not yet in progress.
Development
- In Progress: Someone is assigned and actively working on the task.
- Waiting for Code Review: A PR against
mainis ready for review.
Testing
- Ready to Test: Code has been merged to
main, deployed tomomentum-main.fly.dev, and tested by the ticket owner. Ready for QA handoff. - In QA/Test: QA is actively testing on
momentum-staging.fly.dev
Completion
- QA Verified: QA has verified that all specifications have been met. Any additional issues or edge cases are documented or added to the backlog.
- Done: Task has been completed.
- Done - PR Awaiting Post-Merge Review: Code was pushed without human review and the developer has requested post-merge review.
QA and ticket progression
Section titled “QA and ticket progression”The QA team ensures that User Stories meet their requirements and that Bug fixes resolve the reported issues. If a ticket does not meet the quality threshold, QA keeps it in the testing state and writes sub-tickets for specific faults to be fixed.
Tasks with no intended behavioral change are covered by regression tests and automated testing rather than explicit QA review, and are moved directly to Done after merging.
Risk-Based Code Review Policy
Section titled “Risk-Based Code Review Policy”Pull requests require different levels of review based on risk assessment. Developers evaluate risk considering technical changes, business context, potential impact, and AI-reviewer based complexity and risk assessments. Review requirements range from AI-only for low-risk changes to mandatory human review for high-risk modifications affecting authentication, payments, or core data models.
Medium-risk changes may use either human review or AI review if the developer believes this is justifiable. Special markers like [FF] for feature flags or [PARALLEL] for backward-compatible changes can reduce risk levels.
For detailed guidelines and examples, see the Risk-Based PR Review Policy.
Merges
Section titled “Merges”Once review requirements are met and objections resolved, the developer merges their work into main and moves the ticket to “Ready to Test”.
Creating a release
Section titled “Creating a release”When the criteria for a release have been met, the release conductor runs the Promote to Staging workflow, which:
- Tags the release on
main(e.g.,v2.13.0) - Creates a draft GitHub release with auto-generated notes
- Fast-forwards
stagingto the release tag, triggering a deploy to staging - QA performs end-to-end testing on the staging environment
Promoting to production
Section titled “Promoting to production”Once QA has verified the release on staging, the release conductor runs the Promote to Production workflow, which:
- Fast-forwards
prodto the same release tag, triggering a deploy to production - Verifies the production site responds successfully
- Publishes the draft GitHub release
Because all three branches share the same commits, there is no back-merge step. The release tag permanently marks exactly what was deployed.
Fixing Bugs in Staging
Section titled “Fixing Bugs in Staging”Bugs discovered in staging during pre-release testing are fixed on main and staging is re-promoted. This keeps main as the single source of truth.
- QA writes sub-tickets (Tasks) under the original User Story or Bug ticket for specific faults to be fixed.
- Developer branches from
mainand opens a PR targetingmain - Once merged, bump the patch version (e.g.,
v2.14.0→v2.14.1) and re-run the Promote to Staging workflow - This re-tags and fast-forwards
stagingwith the fix included - QA re-tests on staging — repeat as needed for additional fixes
Fixing Bugs in Production
Section titled “Fixing Bugs in Production”Critical (P0) bugs — hotfix
Section titled “Critical (P0) bugs — hotfix”Hotfixes follow the same principle: fix on main first, then package and promote through the normal workflow. Never commit directly to staging or prod.
- QA or Product writes a Bug ticket (P0)
- Developer fixes the bug on
main(normal PR process) - Create a new patch version (e.g.,
v2.14.1if the release wasv2.14.0) - Run Promote to Staging with the patch version — this tags and fast-forwards
staging - QA does a targeted test on staging (can be abbreviated for critical fixes)
- Run Promote to Production with the patch version
- Post in #tech_change-control that a hotfix was deployed
Non-critical (P1-P3) bugs found in production
Section titled “Non-critical (P1-P3) bugs found in production”- QA or Product writes a Bug ticket (P1-P3)
- P1 bugs get the Must Ship label and are placed in the next Milestone
- P2-P3 bugs are created in the New state for triage by Product
- These are fixed on
mainas normal development work and deployed in the next release
Deployment Automation
Section titled “Deployment Automation”Github actions are set up to support the release cadence.
Merging a pull request to main triggers an automatic deploy to momentum-main.fly.dev. This is expected to be triggered multiple times a day.
Fast-forwarding staging to a release tag triggers an automatic deploy to momentum-staging.fly.dev for pre-release QA.
Fast-forwarding prod to a release tag triggers an automatic deploy to production. Calculation service deployments are done via a manual trigger of a github action. Production releases are expected once per sprint.
Automatic deploys trigger any database migrations that are necessary to bring the environment’s associated database to the current revision.
Tests are automatically run when pull requests are opened. Pull requests cannot be merged if there are failing tests.
Likewise, static code analyzers are run on the codebase when pull requests are opened. Failing static code analysis will block a pull request from being merged.
Monitoring and Observability
Section titled “Monitoring and Observability”After each deployment, automated monitoring tools are used to track system performance, error rates, and user behavior. This helps quickly identify any issues that may have been introduced by the new changes.
Any exceptions triggered in production results in an alert to the development team for immediate investigation.
Quality Assurance
Section titled “Quality Assurance”The QA team is responsible for maintaining the quality of the product. A range of tooling and processes are involved.
At the end of the release cycle, a regression test is performed to check that no features have been inadvertently degraded. These regression tests are formally tracked in test management software.
Automated tests are created by developers, and (as above) are run automatically when pull requests are submitted.
Security testing is regularly performed using an analysis tool named Zed Attack Proxy, which tests server, application and network configuration for weaknesses. The QA team also tests for OWASP related vulnerabilities such a SQL injection. On a regular cadence, a dedicated penetration tester is contracted to conduct a formal test and report.
Load testing is regularly performed to uncover weaknesses in the scaling architecture of the application.
User acceptance testing is continually performed, whereby the QA team and business users of the product will provide feedback if the implementation of features is confusing or cumbersome.
AI-Assisted Development
Section titled “AI-Assisted Development”The team uses AI pair programming tools such as Claude Code and leverages automated code review tools such as CodeRabbit and ZeroPath. AI reviewers provide checks for code quality, security vulnerabilities, and best practices.
AI Context Management: The Momentum-Docs MCP (Model Context Protocol) provides Claude Code with accurate, up-to-date documentation about our codebase. Developers should document stable patterns and domain knowledge in momentum-docs to improve AI assistance accuracy and reduce repetitive searches.
AI Review Comment Policy: All comments from AI reviewers must be addressed by either implementing the suggestion or providing justification for not implementing. This ensures valuable automated insights are not overlooked while maintaining developer discretion. While all comments must be resolved (e.g. via the “Resolve Conversation” button), trivial or repetitive comments may be addressed collectively without individual responses.
The risk-based review policy ensures appropriate human oversight based on the criticality of changes. For detailed AI development practices, see the AI Code Generation Practices.
Agentic Coding
Section titled “Agentic Coding”When AI agents are assigned to complete coding tasks independently (i.e., not pair programming with a developer), the following controls apply:
Task Assignment: AI agents may be assigned well-scoped, straightforward tasks where requirements are clear and the solution approach is understood. Complex tasks requiring architectural decisions, ambiguous requirements, or significant judgment should be assigned to human developers.
Agent Identity: The AI agent must create the pull request under its own identity (e.g., a bot account), not the human user who assigned the task. This ensures the audit trail accurately reflects code authorship.
Mandatory Human Review: All pull requests authored by AI agents MUST receive human review before merging. The human reviewer may use AI-assisted tools to support their review, but a human must approve the change.
Rationale: These controls ensure human accountability for all code changes and maintain an accurate audit trail of authorship. AI-generated code may contain subtle errors, security vulnerabilities, or misunderstandings of business requirements that require human judgment to catch.
Operational Resources
Section titled “Operational Resources”The step-by-step procedures for releases, hotfixes, rollbacks, and CI/CD configuration live in the momentum wiki and the momentum GitHub Actions workflows:
- Release Process — release conductor checklist, hotfix procedures, rollback instructions, and feature flag management
- DevOps Automation 101 — map of all automated workflows, PR lifecycle automation, and ticket status transitions
- PR and Ticket Management — branch naming, PR-to-issue linking, and audit tooling
- Promote to Staging workflow — tags main, fast-forwards staging, creates draft release
- Promote to Production workflow — fast-forwards prod, deploys, publishes release
Policy Review
Section titled “Policy Review”- This policy will be reviewed annually and updated as necessary to reflect changes in our systems, processes, or regulatory requirements.
Internal & Confidential: This page is only available in the internal handbook and contains confidential information.
