ADR-0042: Two-tier branch model with automated release-candidate promotion¶
- Status: Accepted
- Date: 2026-04-17
- Supersedes: none
- Superseded by: none
Context¶
HydraFlow agents land many PRs per day directly on main. Per-PR CI sometimes
passes on flaky scenarios, and integration bugs only surface when multiple
agent changes interact. main is both the integration branch and the release
branch, so a regression landing on main is a regression in "production."
Decision¶
Split the branch model into two tiers:
staging— fast integration branch. Agent PRs target this. Moves frequently. Expected to be usually green but not guaranteed.main— known-good, only advanced via automated release-candidate (RC) promotion PRs that pass the full test gate (unit, scenario, regression, smoke, typecheck, security, ui-build).
Promotion is fully automated: a new StagingPromotionLoop (BaseBackgroundLoop)
cuts a frozen rc/YYYY-MM-DD-HHMM snapshot every rc_cadence_hours (default 4),
opens a PR into main, and merges with gh pr merge --merge --delete-branch
on green. No human approval gate.
Merge strategy is merge commit, not squash. Squash-merging from a
long-lived integration branch produces a growing-diff regression (the next
RC's diff against main includes commits that are logically already on main
but commit-wise are not).
Feature is dark-launched behind HYDRAFLOW_STAGING_ENABLED (default false).
When false, every behavior is identical to the pre-feature state.
Consequences¶
Positive
- main becomes a trustable deploy/rollback baseline.
- Soak window between merge and release catches interaction bugs.
- Per-repo staging_branch + main_branch config generalizes to multi-repo
factory management.
- Rollback is trivial — flip the env flag.
Negative
- p50 time-to-main grows by ~rc_cadence_hours / 2.
- CI YAML must list branch names literally (no dynamic evaluation), so renaming
staging_branch via env var also requires workflow edits. Single-repo scope
today; revisit when the multi-repo factory lands.
- main's history becomes two-tier (first-parent = releases, full = authors).
Use git log --first-parent main for the release view.
Neutral
- RC failures are fail-closed (no rollback needed since main never moves).
A hydraflow-find issue is filed; the next cycle retries.
Alternatives considered¶
- Direct
staging → mainPR (no snapshot). Rejected: PR diff moves while CI runs; never converges under agent PR volume. - Tag-based promotion (no PR). Rejected: loses the PR UI for status checks and audit trail.
- GitHub Actions cron as the scheduler. Rejected: the user wants the release pipeline contained in the factory when HydraFlow begins managing multiple target repos. The loop is a factory capability, not external infra.
- Human approval gate on the promotion PR. Rejected: explicit user goal is full automation.
- Squash-merge of the RC PR. Rejected: produces growing-diff regressions on every subsequent cycle.
References¶
- Spec:
docs/superpowers/specs/2026-04-17-staging-rc-promotion-design.md - Plan:
docs/superpowers/plans/2026-04-17-staging-rc-promotion.md - ADR-0003: Git worktrees for isolation
- ADR-0029: Caretaker loop pattern