Skip to main content

Development workflow

Status: Proposed 2026-09-24

One flow for all four repos. Small branches, one PR each, squash into main. The only repo with a second long-lived branch is the web app, and only once it has real traffic.

Branches​

Branch from main, name with the same prefixes as the commit subjects:

PrefixUse
feat/new behavior
fix/a bug, ideally with the failing test first
docs/documentation only (any repo)
chore/tooling, dependencies, CI
refactor/no behavior change
test/tests only

Short kebab-case after the slash: feat/places-bbox-query. No ticket numbers; the PR is the ticket.

Pull requests​

Every PR starts from .github/pull_request_template.md. The summary block is the completion triple from the principles checklist, plus rollback:

Activist outcome:
What changed:
Privacy and trust checks done:
Signal to watch:
Rollback plan:

Fill it in even for a one-line fix. "Activist outcome: none, tooling" is a valid answer; a blank is not. The checklist below it mirrors the privacy rules and is ticked, not deleted.

Review: CODEOWNERS routes every path to the maintainer. The ruleset requires a code-owner review and a green validate. With one maintainer, the admin bypass covers the review requirement; it never covers the check. Before you push, run npm run validate locally so the PR is green on arrival.

Merge: squash only. The squash subject is a conventional commit subject, because it is the line that shows up in releases.

The web promotion pattern (reserved)​

The web app is the only public surface that redeploys on every merge (Amplify builds main). Once the site has members, the web repo gains a staging branch: feature PRs merge to staging, Amplify builds it as a preview, and one promotion PR moves staging to main. A production-promotion check rejects any PR into main from another branch. Until then the web repo works like the others. The API, mobile, and docs repos do not get a staging branch: the API has a release-directory rollback (backend deployment), mobile has store tracks, docs are docs.

When CI fails​

  1. Open the failed job and read the first error, not the last. Biome and tsc list everything; the first item is usually the cause.
  2. Reproduce locally with npm run validate. If it passes locally and fails in CI, check Node (.nvmrc is the truth), line endings (see linting), and whether a lockfile change was left uncommitted.
  3. Fix, commit, push. Do not re-run a job hoping for a different answer unless it failed on a network step.
  4. If the secrets job fails, stop. Treat the finding as live: rotate the credential first, then remove it from history before the PR merges. Rewriting main is never the fix; rewriting the branch is.

Dependencies​

Dependabot opens grouped minor and patch PRs weekly. Merge them when validate is green; read the changelog for anything that touches auth, crypto, or the map. Major bumps get their own branch and a note in the PR about what was checked by hand.