For contributing (TDD, quality gates, commit style, how to add a route) see CONTRIBUTING.md. This document covers the internal development process: branching model, PR protocol, e2e gate, and release pipeline. For scenario-based GitHub PR triage, external fork handling, and SonarCloud decisions, see docs/GITHUB.md.
feature/* ──┐
fix/* ├──► develop ──► main
docs/* ┘
chore/*
| Branch | Purpose | Merges into |
|---|---|---|
main |
Stable releases only. Tagged. Published to PyPI. | — |
develop |
Integration branch. E2e tests run here. | main (via release PR) |
feature/* |
New capabilities. | develop |
fix/* |
Bug fixes. | develop |
docs/* |
Documentation only. | develop |
chore/* |
Deps, CI, tooling, refactor. | develop |
Nothing merges directly to main. All work flows through develop first.
<type>/<short-kebab-description>
<type>/issue-<N>-<short-kebab-description> # when tracking a GitHub issue
Examples:
feature/issue-16-integration-ergonomics
fix/issue-15-sapisidhash-uploadimage-401
docs/dev-workflow-and-branching-protocol
chore/bump-playwright-1-49
Types mirror Conventional Commits: feature, fix, docs, chore, refactor, test, ci.
- Branch off
develop(notmain). - Use Conventional Commits for all commit messages.
- Open the PR as a draft until all quality gates pass locally.
- Target
developas the base branch. - PR title follows Conventional Commits:
feat(api): ...,fix(cli): ...,docs: ....
uv run python scripts/ci/check_repo_hygiene.py
uv run python scripts/ci/check_doc_links.py
uv run python scripts/ci/check_website_docs_pii.py
uv run python scripts/ci/generate_website_docs.py --check
uv run python scripts/ci/check_council_memory.py
uv run ruff check src tests
uv run ruff format --check src tests
uv run pyright src
uv run python -m pytest -q --cov=gflow_cliCI runs the same nine on every push (this list is kept identical to AGENTS.md's —
/gflow:check runs it plus the CLI↔MCP mirror sweep). Do not bypass with --no-verify.
Project pytest defaults exclude e2e and live; run those credit-spending
tests only with an explicit marker expression and profile/env setup.
Local agents running inside an MCP/context sandbox may need to split the
marker-filtered pytest suite by path and omit coverage locally; CI remains the
authoritative coverage gate.
A sixth gate runs after the scan: the SonarCloud quality gate (new-code
coverage ≥ 80 %, rating A, duplication ≤ 3 %). It blocks merge via
sonar.qualitygate.wait=true, so a failed gate turns the SonarCloud analysis
check red rather than reporting silently on the dashboard. Browser-automation
and live-auth transports are coverage-excluded (e2e-tested, not unit-tested).
See docs/GITHUB.md § SonarCloud Quality Gate.
- Squash merge preferred — keeps
develophistory linear. - The squash commit message becomes the canonical record; make it clean.
- Delete the feature branch after merge.
E2e tests require a live authenticated profile and are not run in CI (video tests spend real Veo credits; image tests cost nothing but draw on a daily image cap). Before opening a develop → main release PR:
export GFLOW_CLI_E2E_PROFILE=<your-profile-name>
uv run pytest -m e2e -vAll @pytest.mark.e2e scenarios must pass. See CONTRIBUTING § E2e tests for the full marker reference.
Version bumps belong in the develop → main release PR, not in feature PRs. The sequence:
- All feature PRs for a release batch are merged to
develop. - E2e gate passes on
develop. - Open a release PR:
develop → main. - In that PR, bump
versioninpyproject.tomland finalizeCHANGELOG.md [Unreleased]→[vX.Y.Z]. - Use the
/releaseskill to automate steps 4 + tagging. - Merge the release PR to
main— CI publishes to PyPI automatically.
Alpha releases use the form vX.Y.ZaN (e.g. v0.6.0a7). Ship alphas from develop → main to validate with real users before cutting a stable vX.Y.Z.
This repo is actively developed with Claude Code (see CLAUDE.md). A few conventions that keep the workflow clean:
- Claude branches are renamed to the appropriate
feature/,fix/,docs/prefix before the PR is opened. Theclaude/prefix is internal scaffolding. - Claude never bumps the version or cuts a release without explicit instruction — use
/release. - Claude opens PRs as drafts targeting
develop. E2E evidence for any change touching a Flow surface is part of the PR, not something the maintainer supplies afterwards (CONTRIBUTING § Test categories); the maintainer reviews, runs e2e only where the author could not, and merges. - Commit messages never carry
Co-Authored-By: Claudeor any AI attribution — author credit is the human maintainer's only.
- CONTRIBUTING.md — TDD, quality gates, how to add a route, commit style
- docs/GOVERNANCE_BENCHMARK.md — calibrating the advisory materiality gate (false-positive / coverage backtest)
- docs/GITHUB.md — GitHub PR triage, external fork handling, SonarCloud scenarios
- RELEASE.md — release checklist, PyPI/GitHub publishing, tag protocol
- CHANGELOG.md — version history
- CLAUDE.md — project memory hub for AI agents