The previous CONTRIBUTING.md read like a stock Rust contributing template that mentioned FIPS. Replace it with an entry-point doc that gives new contributors the FIPS-specific mental model they need to make a useful first PR: the FMP/FSP layering and why mesh-level changes need multi-node testing, the three-branch release model and how to choose a target branch, structured bug reporting expectations, and PR submission requirements (scope discipline, the local-CI ladder, separate requirements for feature PRs vs bug-fix PRs, squash-merge mechanics). Add a contributor-facing AI coding assistant policy: use is welcome, but the contributor must do a thorough manual review and editorial pass before submission. The agent is a tool; the contributor is accountable for the submission. Review effort scales with submission effort -- unreviewed agent output will receive an agent reply in turn, without human review. Add docs/branching.md as the long-form companion covering the release workflow, version conventions, and merge-direction rationale. The new CONTRIBUTING.md is the day-to-day entry point; docs/branching.md is the reference. All cross-references resolve against current HEAD. Previous stale links to fips-intro.md, fips-wire-formats.md, and fips-configuration.md are gone; the doc points at the current docs/design/ layout, docs/getting-started.md, docs/tutorials/join-the-test-mesh.md, and testing/README.md. No code changes.
5.8 KiB
FIPS Branching and Merging Strategy
This document explains how the three long-lived branches relate, when to target each one, and how merges propagate fixes and features. For the day-to-day "how do I send a PR" workflow, see CONTRIBUTING.md.
Branch Structure
Three long-lived branches track parallel development streams:
next ──●──●──●──●──●──────────────●──●── (wire-format-breaking work)
\ /
master ────●──●──●──●──●──●──────●──●──●── (compatible features, latest release line)
\ /
maint ────────●──●──●──●──●────────────── (bug fixes for the latest release)
maint
- Reset to each minor release tag at release time
- Accepts only bug fixes for functionality that shipped in the latest release
- No new features, no API changes, no wire-format changes
- Patch releases tag from here (e.g.,
v0.3.1,v0.3.2) - Periodically merged forward into
masterso fixes propagate
master
- Compatible development for the next feature release
- Multiple feature releases may ship from master (
v0.4.0,v0.5.0) beforenextpromotes - No wire-format breaking changes; no API breaks
- Receives merges from
maintso released-line fixes flow forward - Periodically merged forward into
next
next
- Accumulates work that breaks wire format, API, or compatibility
- Receives merges from
masterso it stays current with bug fixes and compatible feature work - Cargo version on
nextis the expected release version with a-devsuffix, updated ifmasterships additional minor releases first - Becomes the new
masterat the next breaking release; at the same point the oldmasterbecomes the newmaint
Versioning
While the project is in the 0.x era, semver treats minor bumps as
potentially breaking. Both master and next bump the minor version;
the distinction between compatible and breaking is captured in the
changelog and in which branch the work landed on.
The -dev suffix in Cargo.toml indicates an unreleased development
state on the branch.
Merge Direction
Fixes and features flow in one direction only: maint → master → next.
Never merge backward (next into master, or master into maint).
maint ──→ master ──→ next
This guarantees:
- Bug fixes shipped in a release reach all subsequent branches
- Compatible features reach
next - Wire-format-breaking work stays isolated on
nextuntil release
If you submit a PR on next that should also be on master or maint
(rare, since the criteria for needing it on multiple branches are
usually mutually exclusive), the PR stays on its target; the
maintainer either backports as a separate commit on the upstream
branch or asks you to.
Choosing a Branch for Your PR
Pick the branch that matches the scope of your change:
| Your change | Target branch | Why |
|---|---|---|
| Bug fix in a feature that shipped in the latest release | maint |
Fix forward-merges to master and next |
Bug fix in code added on master since the last release (not in any released version) |
master |
The released v0.x.y line is unaffected, so maint does not need the change |
Bug fix in code added on next (wire-format-breaking work) |
next |
The bug only exists where the breaking work exists |
| New feature that does not break wire format or API | master |
Becomes part of the next compatible release |
| Wire-format breaking change, API break, or fundamental protocol shape change | next |
Stays isolated until the next forklift release |
| Documentation, CI, or contributor-facing changes | maint if they apply to released material, else master |
Forward-merges propagate naturally |
If you are not sure, ask in the related issue. The safest defaults
are master for new features and maint for bug fixes; the
maintainer will retarget the PR if needed.
Release Workflow
Bug fix release (from maint)
- Fix on
maint - Bump patch version, tag (e.g.,
v0.3.1) - Merge
maintintomaster - Merge
masterintonext
Compatible feature release (from master)
- Finalize features on
master - Merge
maintintomasterto pick up any pending fixes - Set version, tag (e.g.,
v0.4.0) - Reset
maintto the new tag - Bump
masterto the next-devversion - Merge
masterintonext
Breaking release (from next)
- Finalize features on
next - Merge
masterintonextto pick up pending fixes and features - Assign version as the next minor after
master's last release, tag masterbecomes the newmaintnextbecomes the newmaster- Create a new
nextbranch frommaster
Practical Guidelines
- Commit to the appropriate branch for the scope of the change.
Do not commit bug fixes to
masterwhen they apply to the latest release — put them onmaintand let the forward-merge propagate. - Feature branches base off the long-lived branch they target.
Create with
git checkout -b my-feature maint(ormasterornext), notgit checkout -b my-feature origin/maint. Theorigin/-prefixed form auto-sets the new branch's upstream to the source ref, which can causegit pushto land on the wrong ref under some configurations. - When in doubt about whether a change is compatible, target
next. The maintainer can advise on retargeting. - Resolve merge conflicts on the receiving branch, preserving both the inherited fix and the new development.
- PRs are merged via squash-merge. One logical change per PR becomes one commit on the destination branch, making bisect clean across the integration suite.