> ## Documentation Index
> Fetch the complete documentation index at: https://haico.gr/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ADR-0001: Two-branch model

> Two-branch (develop + main) tag-driven release model.

# 0001. Two-branch model with tag-driven releases

## Context and problem statement

HAI-Co² has two deploy targets: a *dev* environment (always tracking the latest integration) and a *production* environment (only the curated, stable release). The flow from a contributor's first PR to a running production build needs to be obvious to outsiders, reproducible (so any tagged version can be rebuilt and redeployed), and machine-enforceable in CI.

GitHub Flow (one default branch + ephemeral feature branches) is the popular default, but it conflates *integration* with *release*: every push to the main branch is potentially a release. GitFlow, conversely, prescribes five branch types and is heavier than this project needs.

## Decision drivers

* Single tag → reproducible image → exact deploy. No "rebuild on demand."
* A reviewer should be able to look at one diff (`develop` vs. `main`) and see what is about to ship to production.
* The CI workflow must be one file, not a fork-per-environment.
* Public contributors must be able to land changes without coordinating with a release manager.

## Considered options

1. **GitHub Flow**: single `main`, ephemeral branches, deploy from `main`.
2. **GitFlow**: `develop` + `main` + `release/*` + `hotfix/*` + `feature/*`.
3. **Trunk-based with environment tags only**: single `main`, deploy by tag.
4. **Two-branch model: `develop` + `main`, tag-driven releases.** PRs land on `develop`; promotion to `main` is a fast-forward + `vX.Y.Z` tag.

## Decision outcome

**Chosen option: two-branch model with tag-driven releases**, because it preserves a clear "what is about to ship" diff (`develop` vs. `main`) without the ceremony of GitFlow's full branch set.

Tag scheme:

| Tag pattern  | Deploy target | Image tags produced                         |
| ------------ | ------------- | ------------------------------------------- |
| `dev-vX.Y.Z` | Dev env       | `ghcr.io/<owner>/haico-*:dev` + `:X.Y.Z`    |
| `vX.Y.Z`     | Production    | `ghcr.io/<owner>/haico-*:latest` + `:X.Y.Z` |

The single [`CI`](https://github.com/petrosrapto/HAICO/blob/main/.github/workflows/ci.yml) workflow drives both. Tag names must be strict SemVer; anything else is rejected by `resolve-release`.

### Positive consequences

* One PR = one diff against `develop`. Predictable.
* `main` is always exactly what is in production. `git log main` is the release history.
* Tags are immutable; production deploys are byte-equivalent to dev deploys for the same SHA.
* Public contributors only need to know one rule: *target `develop`*.

### Negative consequences

* Two long-lived branches require an explicit promotion step (the `develop → main` fast-forward + tag push).
* When the repo is private (free tier), the GitHub merge-button cannot enforce *Require linear history*, so the promotion has to be done locally. This is documented in [CONTRIBUTING.md](https://github.com/petrosrapto/HAICO/blob/main/CONTRIBUTING.md) and disappears once the repo is public.

## Pros and cons of the options

### GitHub Flow

* **+** Minimal ceremony; what most OSS projects use.
* **−** No staging surface; every push is a release candidate.

### GitFlow

* **+** Explicit release / hotfix branches.
* **−** Five branch types is overkill for a two-environment project.

### Trunk-based + environment tags

* **+** No long-lived branches.
* **−** No "what is about to ship" diff; harder to triage what is in prod.

### Two-branch model (chosen)

* **+** Predictable; documented in one short table; aligns with how dev and prod are actually deployed.
* **−** Requires the promotion fast-forward to stay linear.

## Links

* [`CONTRIBUTING.md`](https://github.com/petrosrapto/HAICO/blob/main/CONTRIBUTING.md), branching and release sections.
* [`README.md`](https://github.com/petrosrapto/HAICO/blob/main/README.md), "Branches, tags & releases" table.
* [`.github/workflows/ci.yml`](https://github.com/petrosrapto/HAICO/blob/main/.github/workflows/ci.yml), the `resolve-release` job that enforces this scheme.
* [`docs/going-public.md`](https://github.com/petrosrapto/HAICO/blob/main/docs/going-public.md), when the GitHub branch protection takes over from the local convention.
