Architecture decision ADR-011

Trunk-Based Development with a Single Production Environment

Superseded · 2026-05-20

Historical decision text is preserved. Accepted describes the decision, not deployment of every capability discussed. Consult the Architecture and Infrastructure tabs for the verified running system.

Supersedes or amends: ADR-010

Successors or amendments: ADR-013, ADR-017

Date: 2026-05-20
Status: Superseded by ADR-013 (2026-05-25)
Supersedes: ADR-010 (3-Branch Gitflow)
Deciders: Daniel Meza

Superseded. This ADR's single-env model was reversed by ADR-013, which re-introduces a staging environment plus an explicit promotion step to production. The trunk-based branching philosophy is preserved; only the environment count and deploy trigger change. Read this ADR for the rationale that led to the single-env experiment and the cost/benefit analysis that justified reversing it.


Context and Problem Statement

ADR-010 (May 2026) prescribed a 3-branch Gitflow (feature/* → develop → staging → main) with three Railway environments (develop, staging, production) and a GitHub Actions–driven CI/CD pipeline. That decision was made anticipating a team of 3+ engineers and a need for staged integration testing.

In practice, the project is operated by a single developer (with AI-assisted development via Claude Code skills) and has no test traffic to differentiate environments. The staging environment was provisioned but never used; the develop environment was used briefly but added overhead without measurable benefit. GitHub Actions has not been wired up — every push has to pass through Railway's native GitHub integration regardless. The branch-and-env multiplicity adds operational cost (3× Railway env config, 3× secret sets, branch sync chores, "is staging up to date" mental tax) with no offsetting benefit at the current team size and traffic level.

This ADR re-decides the branch and environment strategy with the current realities in mind.


Decision Drivers


Considered Options

  1. Keep 3-branch Gitflow (status quo from ADR-010). Continue with develop + staging + main and three Railway environments. Cost: ongoing branch sync overhead, 3× Railway env spend, mental tax of "is staging fresh."
  2. Trunk-based with a single main branch and a single production environment. Feature work on short-lived feature/* branches cut from main; merge to main triggers Railway deploy to production. No develop, no staging, no per-branch environment.
  3. 2-branch flow (main + staging). Drop develop but keep staging as a final pre-prod check. Slightly lighter than option 1 but still pays the staging cost.
  4. Trunk-based with PR preview environments. Single main branch but Railway PR-preview environments per open PR. Adds Railway preview cost but provides per-PR isolated testing.

Decision Outcome

Option 2: Trunk-based development with a single production environment.

Branch structure

Branch Lifetime Purpose Deploys to
main Permanent The trunk — always deployable Production (Railway)
feature/{FEAT-id}-{slug} Short-lived (target: < 5 days) Feature development, cut from main, PR'd back to main — (no auto-deploy in v1)
fix/{description} Short-lived Bug fixes against main —
hotfix/{description} Same as fix/* in this model Urgent production fix — same flow, no separate ceremony —

Promotion path

feature/FEAT-XXX-name ──► main ──► Railway production environment
                         (PR review + local CI)        (auto-deploy via Railway GitHub integration)

Cutting and merging

Cutting a feature branch:

git checkout main
git pull origin main
git checkout -b feature/FEAT-XXX-short-slug

Merging back:

  1. Push the feature branch.
  2. Open a PR to main.
  3. Run /code-reviewer locally (or in conversation) — diffs against main.
  4. Run pnpm lint && pnpm typecheck && pnpm test locally.
  5. Merge the PR (squash or merge commit — your call).
  6. Railway's native GitHub integration redeploys production from the new main tip.

Environment count

Environment Branch Purpose
production (Railway) main The only live environment in v1

There is no develop Railway environment. There is no staging Railway environment. There are no PR preview environments in v1.

CI/CD in v1: local + Railway native

Forward compatibility — re-enabling staging or GitHub Actions

This decision is reversible. The re-enablement path:

  1. Re-add staging: uncomment the staging resources in infra/terraform/railway/environments.tf, re-create the staging branch on GitHub, re-add the staging deploy token variable, re-link the Railway service to the staging branch in the dashboard.
  2. Re-add GitHub Actions: add .github/workflows/{ci,deploy,preview}.yml and switch Railway from "auto-deploy on push" to "deploy from CI". The CI structure described in ADR-010 (preserved as historical context) is the playbook.
  3. Re-add develop: same pattern as staging.

The decision triggers for re-enablement:


Positive Consequences

Negative Consequences / Trade-offs


Pros and Cons of the Options

Option Iteration Speed Safety net Cost Fits team-of-1
1. Keep 3-branch Gitflow Low High (in theory) High No
2. Trunk + single env (chosen) High Low (mitigated by small PRs + local CI) Low Yes
3. 2-branch (main + staging) Medium Medium Medium Marginal
4. Trunk + PR previews Medium-high Medium-high Medium-high Marginal

Option 4 was attractive but adds the cost of preview infra that the single-developer review loop doesn't need today. Worth revisiting when team grows.


Migration from ADR-010

Concrete changes accompanying this ADR (all on the same PR):

After this PR merges:


References