Skip to content

ADR-0004: GitOps everything; promotion is a platform-raised PR

Status: Accepted — product brief (2026-06); confirmed 001-walking-skeleton Principles served: VI Source: docs/design.md D3; specs/001-walking-skeleton/research.md D-3; .specify/memory/constitution.md Principle VI

Context

Promotion from sandbox to production needs an approval step whose audit trail is provable, performed by users who never touch git. The platform itself — including its policy baseline — also needs a delivery path that is versioned and reviewable. Introducing a bespoke approval workflow would create a second audit system beside git.

Decision

Argo CD reconciles everything from git: application code, sandbox and production environments, and platform and policy-baseline updates. A promotion request is a pull request from the sandbox track to the production track in the app's repo, raised by the platform when the user clicks promote, with the evidence record attached by automation. Approval is the merge by the responsible approver, captured in git history and the attestation chain. Merge = deploy. No separate workflow engine is introduced in v1.

Alternatives considered

  • A custom approval/workflow service — rejected: reinvents git review and breaks the git-native audit trail.
  • Argo Rollouts gating — rejected: heavier than needed.

Consequences

The approval audit trail is git-native and one delivery path serves both apps and the platform itself. Promotion requests route to the platform-approver group in Keycloak (mapped to the Gitea PR reviewer group); the PR reflects the snapshot taken at promote time, so iteration continues while a promotion is pending. Two recorded tensions follow from this decision: cost-cap suspension deliberately deviates from the git-commit path (ADR-0012), and dedicated promotion tooling (Kargo) stays deferred until real multi-environment needs appear (ADR-0015). The loop is self-hosting from a fresh cluster: hack/seed-gitea.sh installs Gitea directly, pushes the platform repo into it, and registers the Argo CD credential once, after which the app-of-apps adopts those same manifests and reconciles everything. The bootstrap gap recorded when this ADR was written is closed.