Accepted in its amended form on 2026-10-19 by owner decision SDLC D11, recorded in
0121.
Context
Stackra has no CI file yet.lefthook.yml says a GitLab pipeline is the gate, while the repositories with a working gate
(OIDC secrets, SHA-pinned actions, a single required check) run on GitHub Actions. A repository with two hosts has two
sources of truth about what passes. The choice of host is a human decision; the owner chose GitHub.
Decision
- One host. GitHub, with GitHub Actions as the orchestrator. A repository has either
.github/or.gitlab/, never both. - One required check: a gate workflow that always runs and calls
pnpm verify. Path filters must never skip the required check. - Logic lives in pnpm scripts, not in YAML. Workflow files call
pnpmscripts, so moving host is a rewrite of thin callers. - The same command runs locally. What CI runs, a developer can run with
pnpm verifyand zero secrets. A check that cannot run is a failure, not a skip. - Secrets reach CI only through OIDC (0009). The verify phase has no identity.
- Break-glass. If the host is down, a human may deploy from a developer machine; the deploy is recorded in the repository afterwards.
- Deploy and release jobs are separate workflows that need approval (0013).
Consequences
- Fixing
lefthook.ymlheader (it names.gitlab-ci.yml) is part of accepting this ADR. - Branch protection requires the gate check and nothing else.
- A two-person production rule is not adopted while there is one maintainer; CODEOWNERS applies until a second maintainer joins.
Enforcement
Planned: the gate workflow itself (.github/workflows/gate.yml running pnpm verify), commitlint over the pull-request range,
and gitleaks. Nothing enforces this today: there is no CI file in the repository.
Supersedes and sources
Supersedes: none. Sources: platformdocs/adr/0001-github-code-host-and-ci, 0002, 0012-local-ci, docs/research/gitlab-vs-github.md; academorix ci/README.md; basalt .gitlab/README.md.